对象到通用类型转换的未检查警告的定义在哪里?

时间:2019-03-04 08:29:34

标签: java generics type-conversion warnings javac

JLS 5.1.9定义未经检查的转换,如下所示:

  

让G用n个类型参数命名通用类型声明。

     

原始类或接口类型有未经检查的转换   G表示为G<T1,...,Tn>形式的任何参数化类型。

     

从原始数组类型G[]G<T1,...,Tn>[]形式的任何数组类型类型都有未经检查的转换。

     

使用未经检查的转换会导致编译时未经检查的警告   除非G<...>是其中所有类型实参都在其中的参数化类型   不受限制的通配符,或者不受限制的警告被   SuppressWarnings批注

据我了解,它说如果将原始类型转换为具有受限类型参数的泛型,则会发生未经检查的转换。那么为什么以下代码会生成未经检查的警告:

public class DoubleStar{

    public static void print(Object object){
       ((A<String>)object).print();
    }

    public static void main(String[] args){
        print(new Object());
    }
}

class A<T>{
    public void print(){
        System.out.print("HELLO");
    }
}

由于对象不是原始类型(AFAIK),因此上述代码为什么应生成未经检查的强制转换警告,并且在何处定义了此行为?

2 个答案:

答案 0 :(得分:1)

您正在查看错误的部分,这就是为什么在您的示例上下文中它似乎没有意义。

您的警告是未选中的 cast 。您正在查看有关未选中的转化related)的部分。

See 5.5.2 "Checked Casts and Unchecked Casts"

  

从S类型转换为T类型的转换是静态已知是正确的,当且仅当S <:T   (§4.10)。

     

从类型S转换为参数化类型(第4.5节)T的未检查   除非至少满足以下条件之一:

     
      
  • S <:T
  •   
  • T的所有类型参数(第4.5.1节)都是无界通配符
  •   
  • T <:S和S除了T的类型实参之外,没有X的子类型X   X不包含在T的类型参数中。
  •   
     

除非S <:T,否则不检查从类型S到类型变量T的转换。

     

从S到T的未经检查的强制转换是完全未选中,如果从   | S |至| T |从静态上讲是正确的。不然是   部分未选中

     

未经检查的强制转换会导致编译时未经检查的警告,除非   被SuppressWarnings注释(第9.6.3.5节)取消。

     

如果不是静态已知正确且正确,则检查   未被选中。

     

如果强制转换为引用类型不是编译时错误,则存在   几种情况:

     
      
  • 根据静态信息,演员表是正确的。
  •   
     

不对此类转换执行运行时操作。

     
      
  • 演员表是完全未经检查的演员表。
  •   
     

不对此类转换执行运行时操作。

     
      
  • 演员表是部分未经检查的演员表。
  •   
     

此类强制转换需要运行时有效性检查。执行检查   好像强制转换是| S |之间的选中强制转换和| T |,为   如下所述。

     
      
  • 演员表是已检查的演员表。
  •   
     

此类强制转换需要运行时有效性检查。如果值在运行   时间为空,则允许强制转换。否则,让R为类   由运行时参考值引用的对象的,然后让T   是强制转换运算符中命名的类型的擦除(第4.6节)。演员表   转换必须在运行时检查类R是否为赋值   通过第5.5.3节中的算法与类型T兼容。

     

请注意,首次应用这些规则时,R不能是接口   对于任何给定的转换,但如果应用了规则,则R可能是接口   递归,因为运行时参考值可能引用数组   元素类型是接口类型。

答案 1 :(得分:0)

因为当您将Object转换为A<String>时,编译器无法检查Object确实是{{1} },而不是A<String>(或其他任何内容)。