Java-instanceof vs在运行时转换泛型类:

Java-instanceof vs在运行时转换泛型类:,java,generics,casting,instanceof,Java,Generics,Casting,Instanceof,在Herbert Schildt从Java Complete Reference中提取的代码中: class Gen<T> { T obj; Gen(T o) { ob = o; } T getob() { return ob; } } class Gen2<T> extends Gen<T> { Gen2(T o) { super(o); } } class Test { public sta

在Herbert Schildt从Java Complete Reference中提取的代码中:

class Gen<T> {
  T obj;

  Gen(T o) {
    ob = o;
  }

  T getob() {
    return ob; 
  }
}

class Gen2<T> extends Gen<T> {
  Gen2(T o) {
    super(o);
  }
}

class Test {
  public static void main(String args[]) {
    Gen2<Integer> obj = new Gen2<Integer>(99);
  }
}
class-Gen{
T-obj;
总务(文书主任){
ob=o;
}
T getob(){
返回ob;
}
}
类Gen2扩展了Gen{
第2代(TO){
超级(o);
}
}
课堂测试{
公共静态void main(字符串参数[]){
Gen2 obj=新的Gen2(99);
}
}
他提到instanceof无法在运行时验证对象是否来自类型化泛型类,因为没有可用的泛型信息:

if (obj instanceof Gen2<Integer>) // illegal, doesn't compile
if(Gen2的obj instanceof)//非法,不编译
你只能使用

if (obj instanceof Gen2<?>) // legal
if(Gen2的obj实例)//合法
但是,您仍然可以将同一对象强制转换为(Gen),只要该对象兼容:

(Gen<Integer>) obj // legal
(Gen)obj//legal
但是:

(Gen)obj//非法

这不是Java的矛盾吗?如果Java知道obj可以在运行时转换为Gen,为什么它不知道obj是Gen类/子类的实例呢?

我读了这本书,对此也感到困惑,我发现这可能有帮助:

但是,在某些情况下,编译器知道类型参数始终有效,并允许强制转换。例如:

List<String> list1 = ...;
ArrayList<String> list2 = (ArrayList<String>)list1;  // OK
列表列表1=。。。;
ArrayList list2=(ArrayList)list1;//好啊

我读了这本书,也被这本书弄糊涂了,我发现这本书可能很有用:

但是,在某些情况下,编译器知道类型参数始终有效,并允许强制转换。例如:

List<String> list1 = ...;
ArrayList<String> list2 = (ArrayList<String>)list1;  // OK
列表列表1=。。。;
ArrayList list2=(ArrayList)list1;//好啊

(Gen)obj//非法
”上下文之外,不清楚为什么这一个是非法的,但另一个是允许的。但一般的答案是“因为类型擦除”。我确实理解为什么类型擦除会产生非法调用的实例(擦除会自动删除泛型信息并使从对象到类型的所有转换都透明),但我不理解为什么它不会影响转换。这是我的问题。就像我说的,根据你提供的信息,不可能说为什么第一个演员是合法的,但是第二个演员是非法的。如果
obj
是一个
对象
,并且类型变量是无界的,则其中任何一个都是合法的;如果是更具体的东西,如类型声明的边界所暗示的,那就取决于它们的声明方式,您需要显示声明来说明具体的原因。请将您的问题显示为a。我已从书中添加了相关代码。之前没有提到,但尽管复制链接解释了第一部分,但它没有解释为什么对Gen的角色扮演有效,而对Gen的角色扮演无效(事实上,原始答案甚至没有提到角色扮演)。现在,我提供了完整的示例,您能否详细说明您的答案,以包括对强制转换的解释?这里的区别是,
instanceof
是在运行时计算的,因此只有接受可重新定义的类型作为第二个操作数才有意义,因为这是您可以测试的全部内容。但是,编译时会检查对
Gen
的转换:编译器知道这永远不会安全。你可以通过施放两次来欺骗它:
(Gen)(Gen)obj
;但这并不安全。”
(Gen)obj//lakel
“断章取义,不清楚为什么这一个是非法的,但另一个是允许的。但一般的答案是“因为类型擦除”。我确实理解为什么类型擦除会产生非法调用的实例(擦除会自动删除泛型信息并使从对象到类型的所有转换都透明),但我不理解为什么它不会影响转换。这是我的问题。就像我说的,根据你提供的信息,不可能说为什么第一个演员是合法的,但是第二个演员是非法的。如果
obj
是一个
对象
,并且类型变量是无界的,则其中任何一个都是合法的;如果是更具体的东西,如类型声明的边界所暗示的,那就取决于它们的声明方式,您需要显示声明来说明具体的原因。请将您的问题显示为a。我已从书中添加了相关代码。之前没有提到,但尽管复制链接解释了第一部分,但它没有解释为什么对Gen的角色扮演有效,而对Gen的角色扮演无效(事实上,原始答案甚至没有提到角色扮演)。现在,我提供了完整的示例,您能否详细说明您的答案,以包括对强制转换的解释?这里的区别是,
instanceof
是在运行时计算的,因此只有接受可重新定义的类型作为第二个操作数才有意义,因为这是您可以测试的全部内容。但是,编译时会检查对
Gen
的转换:编译器知道这永远不会安全。你可以通过施放两次来欺骗它:
(Gen)(Gen)obj
;虽然这个链接可以回答这个问题,但最好在这里包含答案的基本部分,并提供链接供参考。如果链接页面发生更改,仅链接的答案可能无效。-@Vikas最初的答案包含了足够的内容。虽然此链接可以回答问题,但最好在此处包含答案的基本部分,并提供链接供参考。如果链接页面发生更改,仅链接的答案可能无效。-@维卡斯最初的回答确实包含了足够的内容。