如何将参数化类作为参数传递
我的目标是开发一个可以输出指定类对象的类。
public class GetMe { public T get() { Object obj = generateObject(); return (T) obj; } }
现在,我知道由于擦除,这是不可能的。 所以,我们可以传入一个类实例并使用它来进行转换。
public class GetMe { public GetMe(Class clazz) { this.clazz = clazz; } public T get() { Object obj = generateObject(); return clazz.cast(obj); } }
这很棒! 只要该类没有参数化。 如果是,那我就有问题了。
我不允许使用List.class
。 如果我传入ParameterizedType(这本身很难生成),则没有使用cast
方法。
有没有办法解决这个泥潭?
我认为超级型令牌可以为您解决这个问题。
List
的问题在于,由于擦除,它在运行时与任何其他List>
无法区分。 最简单的方法是创建一个新的类或接口,其通用部分“固定”,如
public interface StringList extends List { /* nothing to see here */ }
这样你就有了一个类型标记( StringList.class
对象),你可以在运行时传递它并准确指定你想要的东西,但是在运行时不需要generics。
这只是一个小想法。 我不确定它是否适合你的环境,但仍然如此:
public class GetMe { public List getList() { @SuppressWarnings("unchecked") List result = (List ) new LinkedList(); return result; } }
干杯!
第一个问题是您计划如何实例化List
对象。 如果您披露了更多您正在尝试构建的内容,我们可能会更好地帮助您。
您可能希望使用Type而不是Class。 类型可以表示所有generics类型,但使用起来并不愉快。
abstract public class GetMe { Type type; public GetMe (Type type) { this.type = type; } }
另一个问题是如何创建像List
这样的generics类型。 “超类型令牌”在语法上看起来很整洁,实际上它基本上是
static class XX extends TypeReference>{} .... Type typeListString = Util.extract(XX.class);
我更喜欢这种方式
List f; Type typeListString = getDeclaredField("f").getGenericType();
实际上,许多这些花哨的运行时generics魔法的框架只在实例字段上工作。
我认为混淆来自于你正在尝试从List<>
创建一个对象,它面对它是一个接口,而不是一个对象。
所以无论你尝试什么,你都无法创建List<>
的实例,(接口不是实际的类,也没有构造函数)
尝试使用约束来避免在声明中放置接口:
public class GetMe
这将保证T是实际的类而不是接口。