Java —— String类的笔试题
日常开发中用到最多的Java类就是String了,笔试题中也经常会有它的存在。
示例一:
String s = new String("abc"); String s1 = "abc"; String s2 = new String("abc"); System.out.println(s == s1); System.out.println(s == s2); System.out.println(s1 == s2);
结果:
false false false
解析:
很多题目中会将第一行作为一个单独的题目列出,问题是:第一行创建了几个对象,答案是创建了两个,new String("abc")中的"abc"会先在对象池中查找是否存在值为"abc"的对象,没有则创建一个;其二,Java基础中有讲凡是遇到new关键字就会申请内存空间创建对象,所以new又创建了一个值为"abc"的对象,而s仅仅是一个引用而已,它不是对象,它指向new创建出来的"abc"对象的内存地址,该对象是在内存堆中的,而不是对象池中。
第二行,s1指向的是对象池中值为"abc"的对象地址,由于第一行已经在对象池中创建了该对象,所以该行代码没有创建新对象。因此s == s1返回的是false
第三行,与第一行一样,凡是遇到new关键字就会新申请内存地址,很显然s == s2返回false,虽然它俩都是存储在内存堆中,但地址不同
最后,s1 == s2 与 s == s1 是一样的,拿对象池中的对象与内存堆中的对象比较,自然返回false
示例二:
String s = new String("abc"); String s1 = "abc"; String s2 = new String("abc"); System.out.println(s == s1.intern()); System.out.println(s == s2.intern()); System.out.println(s1 == s2.intern());
结果:
false false true
解析:
首先要说的就是String类的intern方法,它是干嘛用的呢?说的通俗一些就是根据调用该方法的对象值去对象池中找与其值相等的对象回来,没有则在对象池中创建一个与其值相等的对象。例如:s1.intern()的含义为:在对象池中寻找值为"abc"的对象,找到就返回,没找到就创建一个,有点强制从池子中带回一个对象的味道。
s == s1.intern() 和 s == s2.intern()
一般看到new出来的字符串对象和其他的字符串对象(无论是否new的还是字面的)使用“==”比较时,不用多想一定是false
s1 == s2.intern()
s1在对象池中,s2.intern()是强制使用对象池中的等值对象,所以它俩是相等的
示例三:
String s1 = "ab"; String s2 = "cd"; String s3 = "ab" + "cd"; String s4 = s1 + s2; String s5 = new String("ab") + new String("cd"); String s6 = new String("ab") + "cd"; String s7 = s1 + "cd"; String s8 = new String("ab") + s2; String s = "abcd"; System.out.println(s3 == s); System.out.println(s4 == s); System.out.println(s5 == s); System.out.println(s6 == s); System.out.println(s7 == s); System.out.println(s8 == s);
结果:
true false false false false false
解析:
该示例考察的是“+”号的用法,只需记住“+”号两边只要有非对象池中的字符串对象那么必然会在内存中创建新对象,如:s4 = s1 + s2是两个应用再做拼接那么会直接在内存中创建值为"abcd"的对象,s6 = new String("ab") + "cd"也是同理。那么,只有在“+”号两侧对象都是字面上的字符串时才会从池子中查找,如:s3 = "ab" + "cd",“+”号两侧的对象都是对象池中的对象,二者拼接后依旧在对象池中查找。