我一直在阅读Java泛型教程和Stackoverflow中涉及泛型的一些线程,但仍无法理解特定情况。 这就是:Java泛型 - 原始类型和参数化类型转换
public class Box<T>
{
private T t;
public T getT()
{
return t;
}
public void setT (T t)
{
this.t = t;
}
public static void main (String[] args)
{
Box<Integer> intBox = new Box<Integer>();
Box rawBox = intBox;
rawBox.setT("NBA");
System.out.println(rawBox.getT());
System.out.println(intBox.getT());
/*1*/ //System.out.println(intBox.getT().toString());
}
}
事情是这样的,第一个打印我的理解,那就是
System.out.println(rawBox.getT());
版画NBA,因为rawBox是原料型箱的T和它“给”我们对象。
我不明白的是第二打印:
System.out.println(intBox.getT());
它打印NBA。 intBox是一个泛型类型(在这种情况下是整数Box),这意味着它的getter方法应该返回一个T类型的值(在这种情况下是Integer),所以我理解的是那里的String对象应该是转换为Integer(因为这是给予Box T的参数类型)并且应该在运行时引发ClassCastException,但它不会发生,为什么?
顺便说一句,评论数/ /增加了混乱,因为如果我取消注释它,它会导致ClassCastException异常在ruuntime(字符串不能转换为整数)被提出,我不t了解
感谢所有:)
首先,很好的回答, 我明白你对println方法的接受,它接受Object类型的参数。 这仍然不解释为什么不调用println方法,下面的语句: intBox.getT();不会引发ClassCastException:String不能转换为Integer。 该声明编译并运行良好。 如果intBox是一个参数化类型(整数),它的getter方法应该返回整数,并且从字符串到整数 的转换应该导致异常从getter方法本身内引发,并且不会发生。 – Michael1
@ Michael1:它将始终由泛型方法的*调用方*来执行强制类型的强制转换。回想一下,没有为每个实例化类型生成一个单独的'.class'文件。换句话说,'Box.class'中没有地方可以将一个强制类型添加到'Integer'中,因为它需要适用于所有类型。它只强制执行参数的*擦除*(在这种情况下,擦除是'对象')。然后调用者被要求在必要时进行演员表演。 –
从[JLS 15.5](https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.5):*有些情况下,静态已知类型可能不是在运行时准确。这种情况可能出现在导致编译时未经检查的警告的程序中。这些警告是针对不能被静态保证为安全的操作给出的,并且**由于涉及不可确定类型**而不能立即进行动态检查。因此,稍后在程序执行过程中动态检查可能会导致运行时类型错误。 –