繁体   English   中英

如何将参数化类作为参数传递

[英]How to pass a parameterized class as an argument

我的目标是开发一个可以输出指定类对象的类。

public class GetMe<T> {
    public T get() {
        Object obj = generateObject();
        return (T) obj;
    }
}

现在,我知道由于擦除,这是不可能的。 因此,我们可以传入一个类实例并使用它来进行转换。

public class GetMe<T> {
    public GetMe<T>(Class<T> clazz) {
        this.clazz = clazz;
    }

    public T get() {
        Object obj = generateObject();
        return clazz.cast(obj);
    }
}

这很棒! 只要该类没有参数化。 如果是,那我就有问题了。

我不允许使用List<String>.class 如果我传入ParameterizedType(这本身很难生成),则没有使用cast方法。

有没有办法摆脱这个泥潭?

我认为超级型令牌可以为您解决这个问题。

List<String>的问题在于,由于擦除,它在运行时与任何其他List<?>无法区分。 最简单的方法是创建一个新的类或接口,其通用部分“固定”,如

public interface StringList extends List<String> {
    /* nothing to see here */
}

这样你就有了一个类型标记( StringList.class对象),你可以在运行时传递它并准确指定你想要的东西,但是在运行时不需要泛型。

这只是一个小想法。 我不确定它是否适合你的环境,但仍然如此:

public class GetMe<T>
{
    public List<T> getList() {
        @SuppressWarnings("unchecked")
        List<T> result = (List<T>) new LinkedList(); 
        return result;
    }
}

干杯!

第一个问题是您计划如何实例化List对象。 如果您披露了更多您正在尝试构建的内容,我们可能会帮助您做得更好。

您可能希望使用Type而不是Class。 类型可以表示所有泛型类型,尽管使用起来并不愉快。

abstract public class GetMe<T> 
{
    Type type;
    public GetMe<T>(Type type) 
    {
        this.type = type;
    }
}

另一个问题是如何创建像List<String>这样的泛型类型。 “超级型令牌”在语法上看起来很整洁,实际上它基本上是

static class XX extends TypeReference<List<String>>{}
....
Type typeListString = Util.extract(XX.class);

我更喜欢这种方式

List<String> f;

Type typeListString = getDeclaredField("f").getGenericType();

实际上,许多这些花哨的运行时泛型魔法的框架只在实例字段上工作。

我认为这种混淆来自于你正试图从List<>创建一个对象,它面对它是一个接口,而不是一个对象。
所以无论你尝试什么,你都无法创建List<>的实例,(接口不是实际的类,也没有构造函数)

尝试使用约束来避免在声明中放置接口:

public class GetMe<T extends Object> 

这将保证T是实际的类而不是接口。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM