您的位置:首页 > 编程语言 > Java开发

解析String与Integer的==

2016-03-17 17:40 295 查看
在Java中有六种不同的储存数据的地方:寄存器、堆栈、堆、静态储存区、常量储存区、非RAM储存区。

寄存器是最快的储存区,但无法人工控制,在编译时会自行分配。堆栈的速度其次,一般用于储存大小与生命周期已知的数据,如基本类型的变量与数据、对象与数组的引用。堆比堆栈更慢,一般用于储存大小与生命周期运行时确定的数据,如new出来的对象。静态储存区用于储存static关键字标记的元素,对象本身不会储存在此区域。常量区用于储存常量,如字符串常量与基本类型常量。

有了这些铺垫,就要回到主题了。下面就要讲到不同String对象s1==s2的判断了。根据个人总结,下面几种情况一定为true。

1)String s1 = “abc”;

String s2 = “abc”;

System.out.println(s1==s2); //true

指向了同一个常量。

2)String s1 = “abc”;

String s2 = “a” + “bc”;

//或者String s2 = “a” + “b“ + ”c”;

//或者String s2 = “ab” + “c”;

System.out.println(s1==s2); //true

由于“a”、“bc”、“ab”、“b”、“c”均为常量,在编译时都会被优化成常量“abc”,所以为true。

3)String s1 =“abc”;

final String s2 = “ab”;

String s3 = s2 + “c”;

System.out.println(s1==s3); //true

当基本类型与String被final修饰时会被当成常量,在编译时等同于两常量相加,所以为true。需要说明的是,如果s2是通过方法获取时不会被当成常量来处理,因为在编译时无法确定s2的内容,所以此时会为false。

1)String s1 = “abc”;

String s2 = new String(“abc”);

System.out.println(s1==s2); //false

s1指向常量池,而s2指向了堆中的“拷贝”。

2)String s1 = “abc”;

String s2 = “ab”;

String s3 = s2 + “c”;

System.out.println(s1==s3); //false

s1指向了常量池中的对象,而s2不是常量,在相加时编译器会优化,使用StringBuilder来完成,最后调用其toString方法来返回一个String对象,所以为false。

接下来就说说Integer中的==。一般情况下两个Integer对象是不会相等的,但由于Integer类中有个叫SMALL_VALUES的数组,保存了从-128到127这256个new出来的对象,每次使用valueOf方法时首先就会判断在不在-128到127这个区间里,如果是就会返回同一个已经初始化的对象,所以下面两种情况都会为true:

Integer i1 = 12;

Integer i2 = Integer.valueOf(12);

Integer i3 = Integer.valueOf(12);

System.out.println(i1==i2); //true

System.out.println(i1==i3); //true

i1会通过调用valueOf方法返回一个Integer对象,所以i1,i2,i3方法都是一样的,由于都小于127且大于-128,返回的都是同一对象,所以都为true。

参考文献:http://www.tuicool.com/articles/FfMJNzU

http://www.tuicool.com/articles/FZjiAnV
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java