请看下面的三行代码。
float f = 1;
float g = 1.1;
float h = 1.1f;
第二行有编译错误,而其他行没有编译错误。第一行工作正常,没有后缀f,第三行使用后缀f。这是为什么?
答案 0 :(得分:21)
默认情况下,Java中的浮点文字值为double
。
JLS 3.10.2 Floating-Point Literals
浮点文字的类型为
float
,如果后缀为ASCII字母F
或f
;否则其类型为double
,并且可以选择以ASCII字母D
或d
为后缀。
如果没有明确的缩小转化,您无法为double
分配float
值。因此,您有两个选择:
f
或F
来表示float
值(float)
后者的一个例子是:
double d = 1.1;
float f = (float) d; // compiles fine!
编译原因:
float f = 1;
是因为从int
到float
的扩展转换可以在作业的上下文中隐式完成。
JLS 5.2 Assignment Conversion
将表达式的值赋给变量时,会发生分配转换:必须将表达式的类型转换为变量的类型。分配上下文允许使用以下之一:
- 扩大原始转换(第5.1.2节)
- [...]
JLS 5.1.2 Widening Primitive Conversion
以下19种关于基元类型的特定转换称为加宽基元转换:
int
至long
,float
或double
- [...]
如上所述,D
还有d
或double
后缀。请考虑以下代码段:
static void f(int i) {
System.out.println("(int)");
}
static void f(double d) {
System.out.println("(double)");
}
//...
f(1); // prints "(int)"
f(1D); // prints "(double)"
还有long
个文字的后缀,即L
或l
(小写字母)。 强烈推荐使用大写变体。
JLS 3.10.1 Integer Literals
如果整数文字的后缀为ASCII字母
long
或L
(l
),则其类型为ell
;否则它是int
类型。后缀L
是首选,因为字母l
(ell
)通常很难与数字1
(one
)区分开来。
答案 1 :(得分:7)
您要为double
变量分配float
值。编译器假定1.1
本身(最后没有加f
)为double
类型。编译器不喜欢进行隐式向下转换,因为它可能会失去精度。
答案 2 :(得分:0)
第一行autocasts int to float(ok)。
由于精度损失,第二行无法将double转换为float。你必须施展:
float g = (float) 1.1;
第三行不需要转换。
答案 3 :(得分:0)
在Java中,每个浮点数(任何带小数点的数字)默认为double
,这比float
更精确。默认情况下,Java不允许您将double
转换为float
,因为精度会降低。
您仍然可以通过投射将double
分配给float
:
float g = (float) 1.1;