java:自动装箱和铸造?

我对一个小问题感到困惑,请参阅以下内容:

Double j = new Double(5); // No problem. double j =5;// //But //Here the problem: Double j = 5; Long k =5; Float g = 5.0; 

我知道解决方案,但我想理解为什么在某些情况下,演员是隐式完成而在其他情况下不是。

没有任何问题

 Double j = new Double(5); 

因为Java会将5int转换为Double构造函数将采用的double 。 它还会将5转换为该行的double精度:

 double j =5; 

这是一个扩大的原始转换。

这些线路存在问题。

 Double j = 5; Long k =5; Float g = 5.0; 

Java将不会隐式执行扩展原始转换( 55.05L )和装箱转换( doubleDoublelongLong )。 它将隐式执行任一个,但不能同时执行两个。 它也不会在这里执行缩小的原始转换( 5.05.0f )。

JLS第5.2节规定:

赋值上下文允许使用以下之一:

  • 身份转换(第5.1.1节)

  • 扩展的原始转换(第5.1.2节)

  • 扩大参考转换(第5.1.5节)

  • 一个拳击转换(第5.1.7节),可选地后跟一个加宽的引用转换

  • 一个拆箱转换(第5.1.8节),可选地后跟一个加宽的基元转换。

它没有明确允许最后3行试图做的事情:扩展原始转换,然后是装箱转换。

有趣的是,Java确实允许:

 Number x = 5; // boxing followed by widening double y = new Integer(5); // unboxing followed by widening 

这三个任务的问题在于尽管Java有关于扩展原始到原始转换的规则,但它没有原始到包装转换的规则。 换句话说,除了自动装箱之外,没有规则可以进行转换。

 Double j = 5; // 5 is an int literal. It can be auto-boxed only to Integer Long k =5; // Same here Float g = 5.0; // 5.0 is a double literal. It can be auto-boxed only to Double 

您可以通过添加适当的后缀或适当的强制转换来修复这些问题,如下所示:

 Double j = (double)5; Long k = 5L; Float g = (float)5.0; 

双j =新双(5); 双k = j;

这里发生了拆箱。 从Wrapper对象获取值并分配给原始数据类型(int,doulbe,float)double k = j; 相当于j.doubleValue(); 返回类型是double

双j = 5;

你想要像这样使用ti,你必须提到数据类型,Double a =(double)5; 或双倍a = Double.valueOf(5);

这是自动装箱。 知道数据类型不能java强制转换,否则你应该给出正确的原始数据类型(5.0)。

double d = 5; //扩大

在上面的陈述中,从原始intdouble发生了扩展

Double d = new Double(5); //包装类构造函数使用并传递int类型值为5,但返回包装类Double引用d引用值5.0,因为jvm将在int类型值5上进行widening并返回由包装类Double constructor使用的double类型5.0。

Double d = 5.0; //是自动拳击,就像Double d = new Double(5);

但是, Double d = 5; //是错误的,因为int类型值5不能auto boxeddouble类型值并由Double类型引用变量引用。 对于要由包装类引用变量引用的值,jvm不执行这种原始类型扩展。