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会将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
或long
到Long
)。 它将隐式执行任一个,但不能同时执行两个。 它也不会在这里执行缩小的原始转换( 5.0
到5.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;
//扩大
在上面的陈述中,从原始int
到double
发生了扩展
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 boxed
为double
类型值并由Double
类型引用变量引用。 对于要由包装类引用变量引用的值,jvm不执行这种原始类型扩展。