编译器指示无法确保类型安全的警告。术语“未经检查”的警告具有误导性。 这并不意味着警告不受任何限制。 术语“未选中”是指编译器和运行时系统没有足够的类型信息来执行确保类型安全所必需的所有类型检查。 从这个意义上说,某些操作是“未经检查”的。“未经检查”警告的最常见来源是使用原始类型。 通过原始类型变量访问对象时会发出“未选中”警告,因为原始类型不提供足够的类型信息来执行所有必要的类型检查。
示例(未经检查的警告与原始类型一起):
warning: [unchecked] unchecked cast
found : java.lang.Object
required: Wrapper
clon = ( Wrapper )super.clone();
^
warning: [unchecked] unchecked cast
found : java.lang.Object
required: T
clon. wrapped = (T)dupl;
警告:[未选中]未选中调用添加(E)作为原始类型java.util.TreeSet的成员 set.add(“ABC”);
^调用add方法时,编译器不知道将String对象添加到集合中是否安全。 如果TreeSet是包含String(或其超类型)的集合,那么它将是安全的。 但是从原型TreeSet提供的类型信息中,编译器无法分辨。 因此,呼叫可能不安全,并发出“未经检查”的警告。
当编译器找到目标类型为参数化类型或类型参数的强制类型转换时,也会报告“未选中”警告。
示例(未经检查的警告以及对参数化类型或类型变量的强制转换):
clon =(Wrapper< T>)super.clone(); //未经检查的警告 } catch(CloneNotSupportedException e){
抛出新的InternalError();
} 尝试{
类<?> clzz = this.wrapped.getClass(); 方法meth = clzz.getMethod(“clone”,new Class [0]); Object dupl = meth.invoke(this.wrapped,new Object [0]); clon.wrapped =(T)dupl; //未经检查的警告 } catch(例外e){} 返回克隆; }}
^警告:[未选中]未经检查的强制转换发现:java.lang.Object要求:T 酷龙。 wrapped =(T)dupl;
如果涉及运行时的动态类型检查,则其目标类型是(具体或有界通配符)参数化类型或类型参数的强制转换是不安全的。 在运行时,只有类型擦除可用,而不是源代码中可见的确切静态类型。 因此,强制转换的运行时部分基于类型擦除而不是精确的静态类型执行。在该示例中,对Wrapper的强制转换将检查从super.clone返回的对象是否为包装器,而不是它是否是具有特定类型成员的包装器。 类似地,类型参数T的强制类型转换为在运行时类型为Object,并且可能完全优化掉。 由于类型擦除,运行时系统无法在运行时执行更有用的类型检查。
在某种程度上,源代码具有误导性,因为它表明执行了对相应目标类型的强制转换,而实际上强制转换的动态部分仅检查目标类型的类型擦除。 发出“未选中”警告是为了吸引程序员注意演员的静态和动态方面之间的这种不匹配。
请参考:什么是“未选中”警告?