解析String与Integer的==

在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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值