【发布时间】:2013-08-20 09:39:32
【问题描述】:
虽然我知道由于类型擦除,您实际上无法在运行时获取泛型的类型,但我想知道是否可以在编译时获取它。
class ObjectHandle<T extends ObjType> {
T obj;
void setObj(T o) {
obj = o;
}
}
class ObjType {}
class SubObjType extends ObjType {}
...
ObjectHandle<SubObjType> handle = new ObjectHandle<SubObjType>();
...
ObjType obj = [method that returns an ObjType];
if(obj instanceof [handle's generic class, here SubObjType]) {
handle.setObj(obj); // cast???
}
这里编译器知道handle 的泛型类型和我想要的东西,所以当我决定时我不必更改handle 和instanceof 检查(和演员表)的类型更改类(在代码中,当然不是在运行时)。
【问题讨论】:
-
但是编译器不知道
obj的类型,所以无论如何你必须使用instanceof。 -
看起来你想要的只是你的 SubObjType 的简写,你可以在 C 中使用 typedef 来做这件事。 Java 没有。
-
如果您不需要通用案例代码,并且您唯一担心的是代码中的实际类可能会发生变化,我只需将
if替换为assert handle instanceof SubObjType。或者您真的希望在代码中实际类型发生更改时跳过handle.setObj调用? -
@VGR:理想的做法是 ObjectHandle 中的一个方法,以确保
setObj()获得正确的类,否则会抛出异常或其他东西。这只是该问题的解决方法。我有一个方法可以从文件中加载不同子类的对象并将它们作为超类(ObjType)返回。虽然obj应该是返回的 SubObjType,但除了在其上使用instanceof之外,没有其他方法可以判断。 -
@Alexei Kaigorodov:为什么编译器需要知道这一点?
obj是一个ObjType,所以检查它与ObjType的子类对我来说似乎是有效的。编译器不应该删除instanceof,而是删除[handle's generic class, here SubObjType],并将其替换为[ObjectHandle< __SubObjType__ > handle] => SubObjType。
标签: java generics compile-time