为什么在 Java 中将 long 转换为 double?

Why is long casted to double in Java?

SSCCE:

public class Test {

    public static void main(String[] args) {
        Long a = new Long(1L);
        new A(a);
    }

    static class A {
        A(int i) {
            System.out.println("int");
        }

        A(double d) {
            System.out.println("double");
        }
    }
}

输出:

double

不会打印任何编译错误,它工作正常并调用 double 参数构造函数。但是为什么?

这取决于类型提升的规则:long 优先转换为 double,而不是 int

A long 总是可以放入 double 虽然 精度 可能会 如果 long 大于 2 的 53 次方。因此您的编译器选择 double 构造函数比 int 构造函数更合适。

(编译器不会进行 dynamic 检查,因为 1L does 适合 int).

因为 long 不 "fit" 在 int 中。

勾选https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html

int 是 4 个字节,而 longdouble 是 8 个字节

因此,很明显,如果将数据转换为 int,则有可能丢失 4 个字节的数据。数据类型总是向上转换。正如@Bathsheba 的评论提到的,即使使用double 也有可能丢失数据,但与int 相比丢失要小得多。

如您所见,double 使用 52 位存储有效数字。如果它选择 int,变量将有 32 位可用。因此 jvm 选择 double 而不是 int。

来源:Wikipedia

long 转换为 intnarrowing primitive conversion because it can lose the overall magnitude of the value. Converting long to double is a widening primitive conversion

编译器将自动为参数生成 assignment context 转换。这包括扩大原始转换,但不包括缩小原始转换。因为带有 int 参数的方法需要缩小转换,所以它不适用于调用。