Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java泛型:将原始类型强制转换为任何可重新定义的类型不会';不生成未检查的强制类型转换警告_Java_Generics - Fatal编程技术网

Java泛型:将原始类型强制转换为任何可重新定义的类型不会';不生成未检查的强制类型转换警告

Java泛型:将原始类型强制转换为任何可重新定义的类型不会';不生成未检查的强制类型转换警告,java,generics,Java,Generics,关于以下代码,我有以下问题: public class GenericBridgeMethods <T> { public static void main(String[] args) { List obj = new ArrayList<Integer>(); List <?> l1 = (List<?>) obj; // clause 1 GenericBridgeMethods &l

关于以下代码,我有以下问题:

public class GenericBridgeMethods <T> {

    public static void main(String[] args) {
        List obj = new ArrayList<Integer>();
        List <?> l1 = (List<?>) obj; // clause 1
        GenericBridgeMethods <?> g1 = (GenericBridgeMethods<?>) obj; // clause 2
   }

}
公共类GenericBridgeMethods{
公共静态void main(字符串[]args){
List obj=new ArrayList();
List l1=(List)obj;//第1条
GenericBridgeMethods g1=(GenericBridgeMethods)obj;//子句2
}
}
a。第1条当然不会给出未经检查的演员阵容警告
B第2条也没有给出未经检查的演员阵容警告

我注意到,从原始类型(obj)转换为任何可重新定义的类型(如GenericBridgeMethods或GenericBridgeMethods)不会给出未检查的转换警告。如果运行此代码,第2条将出现运行时错误

编译器不应该在第2条中给出警告吗

编辑1:

    ArrayList a1 = new ArrayList<Integer>(); // clause 3
    Number n1 = (Number)a1; // clause 4 ERROR
    Comparable c1 = (Comparable)a1; // clause 5

    List l1 = new ArrayList<Integer>(); // clause 6
    Number n2 = (Number)l1; // clause 7
    Comparable c2 = (Comparable)l1; // clause 8
ArrayList a1=新建ArrayList();//第3条
编号n1=(编号)a1;//第4条错误
可比c1=(可比)a1;//第5条
列表l1=新的ArrayList();//第6条
编号n2=(编号)l1;//第7条
可比c2=(可比)l1;//第8条

有人能解释为什么只有第4条有错误吗?

首先,在您定义的
GenericBridgeMethods
中,
T
不是可修改的类型。Reifiable意味着该类型将被编码到类中,并在运行时可用。对于
T
,情况并非如此

第2条没有给出运行时警告,因为它已被选中:将进行运行时检查,确保
obj
的类型可分配给
GenericBridgeMethods
类型。由于您选择了通配符作为类型参数,因此无需检查
T

另一方面,如果你做了这样的事情:

GenericBridgeMethods<String> g1 = (GenericBridgeMethods<String>) obj;
编辑 如果您不明白为什么编译器允许您尝试将
列表
强制转换为
GenericBridgeMethods
,那么答案是因为编译器无法知道
GenericBridgeMethods
及其子类的整个层次结构。可能有一个子类
GenericBridgeMethods
实现了
List
,在这种情况下,强制转换可能是合法的

但是,如果将
GenericBridgeMethods
设置为最终类(从而阻止它拥有子类),则会出现编译错误。在这种情况下,您将得到一个不可逆类型错误

为了向您展示您的问题与可修订类型和泛型没有多大关系,请看以下内容:

public static void main(String[] args) {
   List obj = new ArrayList<Integer>();

   //this is allowed (no warning), even though it will fail at runtime
   CharSequence sequence = (CharSequence) obj; 
}
你想知道为什么只有“第4条”没有编译。我想我已经在上面和评论中解释了这一点,但我会一步一步地为您介绍这个具体的例子

ArrayList a1 = new ArrayList<Integer>(); // clause 3
Number n1 = (Number)a1; // clause 4 ERROR
由于
Comparable
是一个接口,
ArrayList
的子类可能是
Comparable

List l1 = new ArrayList<Integer>(); // clause 6
Number n2 = (Number)l1; // clause 7
List l1=new ArrayList();//第6条
编号n2=(编号)l1;//第7条

由于
List
是一个接口,
Number
的子类可以实现
List
。编译器在检查转换时不知道
l1
持有
ArrayList

子句1和2处的转换是否转换为可修改类型。这就是我的意思。第2条确实给出了一个运行时错误!这是错误-java.lang.ClassCastException:java.util.ArrayList不能强制转换为GenericBridgeMethod。@yapkm01:java库中没有运行时警告。它当然会失败,因为ArrayList不是GenericBridgeMethod。但是编译器无法知道,因为可能存在实现
List
GenericBridgeMethod
的子类。很抱歉,我将其更改为error。对它给出了一个运行时错误。如果是这种情况,编译器应该给出一个未检查的强制转换warning@yap:未选中的强制类型转换与泛型有关。你的问题真的与泛型无关;他们在掩盖这个问题。这根本不是关于可偿还性。未选中的警告意味着强制转换不会在运行时实际检查类型;在这里你不会明白这一点,因为很明显,类型确实在运行时被检查过(否则你不会得到
ClassCastException
!!)。我在回答中说了这一点,但我要重申:unchecked并不意味着“在编译时未检查”,它意味着“在运行时未检查”。
ArrayList a1 = new ArrayList<Integer>(); // clause 3
Number n1 = (Number)a1; // clause 4 ERROR
ArrayList a1 = new ArrayList<Integer>(); // clause 3
Comparable c1 = (Comparable)a1; // clause 5
List l1 = new ArrayList<Integer>(); // clause 6
Number n2 = (Number)l1; // clause 7