制作供内部使用的API,我需要一些Java抽象,我不知道该怎么做。
我有一个工厂/池类 F ,我想从中获取实例列表(或集合或类似集合)。 我想要的基本上是这样的:
List<B> instances = F.getAllSuitableInstances(parameters);
将我的参数指定的所有实例作为B的集合。
首次尝试使用此功能签名
public List<A> getAllSuitableInstances(parameters);
但是当我尝试将结果列表转换为List以供使用时,我 告诉“不兼容的类型” - 即使B来自A。
所以我尝试了java库的功能:
public <T> List<T> getAllSuitableInstances(parameters, T);
并尝试使用B作为第二个参数调用它。但这不起作用 或者,因为T必须由于某种原因作为实例提供,并且 接口不能有实例。
我知道我可以使用<?>
进行投射,但我希望尽可能使其成为类型安全。
那么,完成这项工作的最佳方式是什么?
答案 0 :(得分:1)
即使B来自A。
你必须要小心--Java的泛型是不变的,这意味着Something<Superclass>
不是Something<Subclass>
的超类(例如List<Number>
不 List<Integer>
的超类。关于此问题有很多问题,因此我不会重复其他人可以更有效地解释的信息,例如here和here。
至于你的第二个签名,在我看来T
中的(parameters, T)
是不必要的。
public <T> List<T> getAllSuitableInstance(parameters);
应该有效,除非我误解了你的要求。这样做的缺点是T
可能任何,因此您可以在类型为T
的对象上调用的方法有所限制,但如果您不是这样做就没有必要担心了。
如果你的接口中的方法是必要的,以使你的方法工作(看起来不像,但以防万一),你总是可以添加边界(例如public <T extends A> List<T>...
)到你的泛型类型,所以编译器知道方法中T
的所有实例都是A
类型或A
的子类型。
如果您需要在方法中使用T
的类型(例如instanceof
检查),则一个选项是传入Class
对象,使用其方法执行运行时等效的instanceof
检查和转换(以及其他选项):
public <T> List<T> getAllSuitableInstance(parameters, Class<? extends T> clazz); // Might be able to use just Class<T> too
希望这会有所帮助。如果我对你需要的东西出错了,请告诉我。
答案 1 :(得分:1)
在使用泛型编程时,这是一个常见的误解,但这是一个重要的学习概念
当我们有两种具体类型A
和B
时(例如,Number
和Integer
),MyClass<A>
与{{1}无关},无论MyClass<B>
和A
是否相关。
B
的共同父母。
无需像第二个选项中提到的那样传递课程
这应该对你有用
MyClass<A> and MyClass<B> is Object