3

有人可以解释一下这个结果吗?

好吧,这是我的代码:

public class foo <T> {

    public static void main(String[] args) {

        foo Foo = new foo();
        System.out.println(Foo.compare(100L, 100));
        System.out.println(Foo.compare(100L, 100L));
        System.out.println(Foo.compare(127L, 127L));
        System.out.println(Foo.compare(128L, 128L));

        System.out.println();
        System.out.println(System.getProperty("java.vendor"));
        System.out.println(System.getProperty("java.version"));

    }

    public boolean compare( T val1, T val2) {
        return ( val1 == val2 ) ? true : false;
    }

}

结果是:

false
true
true
false


Sun Microsystems Inc.
1.6.0_26

首先:

这很奇怪,因为我只声明了一个模板类“T”。第一个比较结果是假的,因为 val1 很长,而 val2 是 int(我已经通过调试器检查过)。但它不应该是,因为我只声明了一个模板类并且两者都相同。

其次:

为什么每个大于 127 的“长”大数字都不相等?

谢谢!

4

3 回答 3

3

在您的比较函数中,您正在比较引用而不是值(== 运算符始终比较引用,除非它是内置类型。请参阅这篇文章What is the difference between == vs equals() in Java?)。

当您使用泛型时,您的内置类型被打包到 java 类中(例如 Integer)。

所以一般来说,这段代码会给你所有的错误,但在这种情况下,你在第二个和第三个例子中是真的,因为 java 编译器缓存范围 [-128, 127] 中的数字,因为它们经常被使用,所以它们在内存中具有相同的地址.

于 2013-06-22T23:19:52.100 回答
3

第一个比较结果是假的,因为 val1 很长,而 val2 是 int(我已经通过调试器检查过)。但这不应该是,因为我只声明了一个模板类,并且两者都相同。

因为,您使用foo Foo = new foo();而不是foo<Long> Foo = new foo<Long>();这样,foo将任何对象视为参数(因为编译后,编译器会删除所有类型参数,如果类型参数有界,则将每个类型参数替换为其第一个边界,如果类型参数无界,则将其替换为 Object

为什么每个大于 127 的“长”大数字都不相等?

因为,您正在比较 line 中变量的引用val1 == val2,而不是这些变量指向的对象中包含的值。

现在,我想加入一个问题:

为什么每个long小于数127和大于数-128都相等?

因为JLS5.1.7

如果被装箱的值 p 是真、假、一个字节或 \u0000 到 \u007f 范围内的一个字符,或者一个介于-128 和 127 (含)之间的 int 或短数字,则令 r1 和 r2 为p 的任意两个拳击转换。r1 == r2 总是如此

于 2013-06-22T23:21:31.180 回答
2

您需要使用equals而不是==执行相等性检查,因为 T 是对象而不是原语:

public static void main(String[] args) {

    foo Foo = new foo();
    System.out.println(Foo.compare(100L, 100));
    System.out.println(Foo.compare(100L, 100L));
    System.out.println(Foo.compare(127L, 127L));
    System.out.println(Foo.compare(128L, 128L));

    System.out.println();
    System.out.println(System.getProperty("java.vendor"));
    System.out.println(System.getProperty("java.version"));

}

public boolean compare( T val1, T val2) {
    return ( val1.equals(val2) ) ? true : false; // use equal instead
}

这给了你:

false
true
true
true

第一个false是由于它的两个输入的类型不相同,因此有一个潜在的转换导致它们的差异。

于 2013-06-22T23:21:04.940 回答