【发布时间】:2016-07-19 07:30:43
【问题描述】:
我了解泛型和转换,但我不了解泛型转换。我以为我只能通过继承树向上或向下转换为特定类型,但这证明我错了:
ArrayList<?> cislo = (ArrayList<? extends Number>) new ArrayList<Integer>();
这可能不是最好的例子,但希望你能明白我的意思。这是如何运作的?它被转换成什么类型?
【问题讨论】:
-
在运行时根本没有强制转换,因为通用信息丢失(类型擦除)。在编译时,您告诉编译器将
ArrayList<Integer>处理为ArrayList<? extends Number>并保持安静(除了警告,基本上它与将Number变量转换为Integer相同 - 你告诉你知道你在做什么的编译器)。对ArrayList<?>的分配在任何情况下都有效。 -
使用泛型,根本不需要强制转换。如果您想转换一个 Generic 类型,也许您应该使用泛型具有的巨大灵活性来检查是否没有不进行转换的“干净”解决方案。如果你有一个具体的例子,我相信很多人都愿意提供帮助。
-
我确实有具体的例子。我使用允许注释 JUnit 测试以选择存储的框架我想将结果发送到例如
@ReesmoConfiguration(storage = RestApiStorage.class)并且在抽象超类 Storage 中我找到了工厂方法newInstance(Object configuration){ Class<? extends Storage> clazz = null; if (Bool.FALSE.equals(Property.ENABLED.get(configuration))) { clazz = DummyStorage.class; } else { clazz = (Class<? extends Storage>) Property.STORAGE.get(configuration); } if (clazz.isAssignableFrom(DummyStorage.class)) { return new DummyStorage(); }} -
好的,这基本上是
Class<? extends Storage> clazz = (Class<? extends Storage>) Property.STORAGE.get(configuration);- 如果get返回的对象是Storage. The cast is necessary if the return type ofget 的子类型的类对象,那么这将起作用@get` 是那个的超类型(比如Object或者一些接口)