我对一个小问题感到困惑,请参阅以下内容:
Double j = new Double(5); // No problem.
double j =5;//
//But
//Here the problem:
Double j = 5;
Long k =5;
Float g = 5.0;
我知道解决方案,但我想理解为什么在某些情况下,演员是隐式完成而在其他情况下不是。
答案 0 :(得分:6)
没有错
Double j = new Double(5);
因为Java会将5
从int
转换为double
构造函数所需的Double
。它还会将5
转换为double
行:
double j =5;
这是一个扩大的原始转换。
这些线路存在问题。
Double j = 5;
Long k =5;
Float g = 5.0;
Java不会执行扩展的原始转换(5
到5.0
或5L
)和装箱转换(double
到Double
或{{1 } {}} {} {} {}}}它将隐式执行任一个,但不会同时执行。它也不会在此处执行缩小的原始转换(long
到Long
)。
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;
//扩大
在上述声明中,从原始int
到double
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不能是int
到auto boxed
类型值,并且由double
类型引用变量引用。对于要由包装类引用变量引用的值,jvm不执行这种原始类型扩展。