如果我们可以将一个Integer对象转换为Object并将一个Integer转换为int,为什么不能将同一对象转换为int?

时间:2019-04-04 17:40:09

标签: java

如果我们可以将一个Integer对象转换为Object并将一个Integer转换为int,为什么我们不能将相同的Object类型转换为int?

Integer i=new Integer(5);
Object p=i;
int s=p;//gives error

2 个答案:

答案 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

在您的示例中看到了相同的内容。 IntegerObject的子代,这就是我们可以做到的原因

Integer i = 5;
Object o = i;

同样,我们不能相反

Object o = new Object();
Integer i = o;  // Not allowed

并且因为在您的示例中我们需要从Object -> Integer -> int(通过取消装箱)进入,所以不允许从ObjectInteger的第二步。


现在,如果您确实编写了类似的代码

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,那么编译器将如何知道intp-object字符串或双精度等。因此,要解决此问题,您必须像这样明确地向下转换:

int

注意:错误的向下转换会抛出int s = (int) p;