如果我们可以将一个Integer对象转换为Object并将一个Integer转换为int,为什么我们不能将相同的Object类型转换为int?
Integer i=new Integer(5);
Object p=i;
int s=p;//gives error
答案 0 :(得分:1)
编译器不知道类型Object
实际上是整数。在您看来,您可以清楚地看到您正在分配一个整数,并且该整数将转换为整数对象。但是,一旦将其分配给Object
,该信息就会因源代码的语义目的而丢失。
代码错误的原因相同:
Object o = getSomeObject(); // What exactly does it return? We don't know
int i = o; // How do you know this will work?
函数getSomeObject()
可以返回任何内容。我们不知道它是整数,字符串还是ArrayList ...,因此我们必须假定它是不安全的转换。如果以上对您有意义,那么您可以推断出无法进行转换的示例。
现在,我认为让您感到困惑的部分是:“我清楚地在其中放入一个整数,该整数会自动装箱到Integer
中,应该通过拆箱进行分配!”
...但是,语言规则规定,一旦执行该赋值,就必须将其视为可以是该类型的任何对象。由于我们不能盲目地假设对象是整数,因此需要显式转换它。
这在提升多态性的层次链中也起着作用。如果您有一个父P以及一个从P扩展过来的子C,那么我们知道:
Child c = new Child();
Parent p = c; // Valid, because c is definitely a Parent
但是
Parent p = new Parent();
Child c = p; // Can't go down the hierarchy, this is also wrong
在您的示例中看到了相同的内容。 Integer
是Object
的子代,这就是我们可以做到的原因
Integer i = 5;
Object o = i;
同样,我们不能相反
Object o = new Object();
Integer i = o; // Not allowed
并且因为在您的示例中我们需要从Object -> Integer -> int
(通过取消装箱)进入,所以不允许从Object
到Integer
的第二步。
现在,如果您确实编写了类似的代码
Integer i = new Integer(5);
Object p = i;
int s = (Integer) p;
这将起作用。实际上,JVM 在运行时(通过HotSpot)很可能会注意到您在做什么,并将上面的代码转换为:
int s = 5;
因为JVM可能足够聪明,可以准确地实现您作为人类实现的目标。
因此,尽管您必须编写 em 正确的Java源代码(当等号的右边为int i = someObj
时,这样做不是Object
),但是编译器可能很聪明,可以在您运行程序时为您内联所有代码。
答案 1 :(得分:0)
Upcasting
强制转换为超类型在您的情况下,object
强制转换为子类型 downcasting
。始终允许向上转换,但是向下转换涉及类型检查。
int
在这里,您正在做Object p=i;
,因为它Upcasting
有意义,所以始终可以这样做。
int is an Object
这里int s = p;
是p
,而您正试图将其分配给子类型object
,那么编译器将如何知道int
是p-object
字符串或双精度等。因此,要解决此问题,您必须像这样明确地向下转换:
int
注意:错误的向下转换会抛出int s = (int) p;
。