java:自动装箱和铸造?

时间:2014-06-20 17:11:28

标签: java autoboxing

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

Double j = new Double(5); // No problem.
double j =5;//

         //But

//Here the problem:

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

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

4 个答案:

答案 0 :(得分:6)

没有错
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)和装箱转换(doubleDouble或{{1 } {}} {} {} {}}}它将隐式执行任一个,但不会同时执行。它也不会在此处执行缩小的原始转换(longLong)。

JLS, Section 5.2,声明:

  

分配上下文允许使用以下之一:

     
      
  • 身份转换(第5.1.1节)

  •   
  • 扩大原始转换(第5.1.2节)

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

  •   
  • 拳击转换(§5.1.7),可选地后跟扩展参考转换

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

  •   

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

有趣的是,Java确实允许:

5.0

答案 1 :(得分:3)

这三个任务的问题在于尽管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;

答案 2 :(得分:1)

Double j = new Double(5); 双k = j;

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

Double j = 5;

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

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

答案 3 :(得分:0)

double d = 5; //扩大

在上述声明中,从原始intdouble

正在扩大

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

constructor //是自动装箱,与Double d = 5.0;

相同

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