Java的auto-boxing与对象实例的比较


运行下面的程序:

public class test {
    public static void main(String[] args) {
        Object a = new Object();
        Object b = new Object();
        System.out.println(a == b);
    }
}

得到的结果是false,因为用==比较两个对象,系统会去比较此两个对象实例的内存地址,不同的对象实例,内存地址是不同的,所以结果会是false,因此我们正确地比较对象实例的方法是使用equal()方法。

再运行下面的程序:

public class test {
    public static void main(String[] args) {
        Integer a = new Integer(1);
        Integer b = new Integer(1);
        System.out.println(a == b);
    }
}

得到的结果也是和上面一样,不同的对象实例,内存地址是不同的。

请再运行下面的程序:

public class test {
    public static void main(String[] args) {
        Integer a = 1;
        Integer b = 1;
        System.out.println(a == b);
    }
}

这次的结果会不会也和前面一样呢?答案是true。

为什么同样是2个对象用==做比较,结果会不一样呢?这个程序和上面一个唯一的区别就是这里使用了auto-boxing把一个primitive的类型自动转化成wrapper class对象,既然是2个Integer的实例对象,为什么会内存地址相等呢?

原来按照Java虚拟机的规范:特定的primitive一定得被auto-box成相同的不可变的wrapper class对象,这些对象会被高速缓存以便重复使用。这些特定的值包括:boolean值的false与true,所有的byte值,介于-128到128之间的short和int值,以及介于0到0x7f之间的所有char值。

所以,运行下面的程序我们就知道,结果一定是false:

public class test {
    public static void main(String[] args) {
        Integer a = 256;
        Integer b = 256;
        System.out.println(a == b);
    }
}

因为256不在这个特定的范围以内。

务必注意这个问题,不然会引入一些古怪的错误。

相关内容