[英]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.