我正在使用Java 8。
我最近遇到了这个问题:
public class Test {
public static void main(String[] args) {
String ss = "" + (Test.<Integer>abc(2));
System.out.println(Test.<Integer>abc(2));
}
public static <T> T abc(T a) {
String s = "adsa";
return (T) s;
}
}
这不会引发java.lang.ClassCastException。为什么会这样?
我一直以为+
和System.out.println
叫toString
。但是当我尝试这样做时,它会按预期抛出异常。
String sss = (Test.<Integer>abc(2)).toString();
答案 0 :(得分:12)
它不会抛出ClassCastException
,因为所有通用类型信息都已从编译后的代码中剥离(称为type erasure的过程)。基本上,任何类型参数都由Object
代替。这就是第一个版本起作用的原因。这也是代码完全编译的原因。如果您要求编译器使用-Xlint:unchecked
标志警告未经检查或不安全的操作,则会在return
的{{1}}语句中收到有关未经检查的强制转换的警告。
使用以下语句:
abc()
故事有点不同。当类型参数String sss = (Test.<Integer>abc(2)).toString();
替换为T
时,调用代码将转换为字节码,该字节码将结果显式转换为Object
。好像代码是使用带有签名Integer
的方法编写的,并且语句是这样编写的:
static Object abc(Object)
也就是说,String sss = ((Integer) Test.abc(Integer.valueOf(2))).toString();
内部的转换不仅会由于类型擦除而消失,而且编译器还会在调用代码中插入新的转换。该强制类型转换在运行时生成abc()
,因为从ClassCastException
返回的对象是abc()
,而不是String
。
请注意,声明
Integer
不需要强制转换,因为编译器只是将String ss = "" + (Test.<Integer>abc(2));
返回的对象馈送到对象的字符串连接操作中。 (有关此操作的详细信息,随Java编译器的不同而不同,但是它要么是对abc()
附加方法的调用,要么是从Java 9开始,是对StringBuilder
创建的方法的调用。)这里的细节无关紧要;关键是编译器足够聪明,可以识别出不需要强制转换。
答案 1 :(得分:6)
泛型在运行时消失,因此对import matplotlib.pyplot as plt
# Pie chart, where the slices will be ordered and plotted counter-clockwise:
labels = 'Frogs', 'Hogs', 'Dogs', 'Logs'
sizes = [15, 30, 45, 10]
explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs')
fig1, ax1 = plt.subplots()
ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
shadow=True, startangle=90)
ax1.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.
plt.show()
的强制转换实际上只是对T
的强制转换(编译器实际上将摆脱它),因此没有类强制转换异常。
Object
只是一种获取对象并返回对象的方法。 abc
是被调用的方法,从字节码可以看出:
StringBuilder.append(Object)
完成时
...
16: invokestatic #7 // Method abc:(Ljava/lang/Object;)Ljava/lang/Object;
19: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
...
然后字节码是
String sss = (Test.<Integer>abc(2)).toString();
您的代码在checkcast
operation处失败,该密码以前不存在。