我不明白为什么代码片段 1 工作正常,但代码片段 2 给出编译时错误 incompatible types: java.lang.Long cannot be converted to int
与java中转换的优先级有关吗?我经历过这个thread on stackoverflow ,但这没有帮助。
请详细解释这两个代码片段的幕后发生的情况以及为什么在代码片段 1 中没有给出错误。
代码片段1:
package com.company;
public class Main
{
public static void main(String[] args)
{
double dbl = 10.25;
int i1 = (int)Math.round(dbl);
}
}
代码片段2:
package com.company;
public class Main
{
public static void main(String[] args)
{
double dbl = 10.25;
Long lng = Math.round(dbl);
int i2 = (int)lng;
}
}
最佳答案
让我们仔细看看会发生什么。在代码段 1 中:
double dbl = 10.25;
int i1 = (int) Math.round(dbl);
您声明一个double
。四舍五入后的结果是long
。然后是向 int
的强制转换,这是可能的,因为两者都是原始类型,Java 允许强制转换。然后将其存储在 int
中。
在片段 2 中,情况发生了一些变化:
double dbl = 10.25;
Long lng = Math.round(dbl);
int i2 = (int) lng;
您声明一个 double
,round 返回一个 long
,但您希望将其存储在 Long
中。所以Java会自动将long
转换为Long
,这就是自动装箱。 Java 可以将所有原始类型包装到其包装类中。
最后您尝试将 Long
转换为 int
但这是不可能的,因为 Long
现在是一个对象。不过,它可以自动将 Long
拆箱为 long
。从那里您可以转到int
。让我们首先看一下这两个变体:
int i2 = (long) lng; // Make unboxing explicit by casting
int i2 = lng.longValue() // Use unboxing method
但是它也不会编译,因为:
incompatible types: possible lossy conversion from long to int
因此转换是可能的,但编译器警告我们,long
可能不适合 int
(有损转换),因此它阻止我们这样做。
但是,我们可以通过强制转换再次使其显式来进行转换:
int i2 = (int) lng.longValue() // The whole process completely explicit
或者,如果您有 Java 8,请使用 Math#toIntExact
( documentation ),如果 long
不适合 int
:
int i2 = Math.toIntExact(lng.longValue());
请注意,Java 不会将您的 Long
拆箱为 long
,然后自动将其转换为 int
,您需要进行拆箱自行明确,如图所示。
这只是 JVM 的转换规则之一,在本例中可能是为了防止无意的编程错误。
关于java - 在 Java 1.8.0_152 中使用 Math.round(double d) 时转换为 int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47367045/