一、以下语句分别创建了几个对象?
String s = new String( "abc" );
String s1 = "abc";
String s2 = new String( "abc" );
- 首先需要明白,s、s1、s2都是引用变量,其值是对象的地址,而不是对象。
- new一个String对象时,首先到String Pool(String 池)中查找是否存在内容为"abc"的对象,若存在,则在堆区创建一个值为"abc“的新的对象,并返回该对象的地址;若不存在,则在Pool中创建一个”abc"的对象,并在堆区也创建一个"abc“的对象,最终返回堆区新创建的对象地址。
- s1 = "abc"中的"abc"是字面值(常量),引用变量s1指向Pool中的"abc”对象,若Pool中没有"abc"对象,则创建一个“abc"放入Pool,并返回Pool中的对象地址。
执行第一条语句:第一次创建"abc"时,Pool中没有"abc"对象,于是创建一个"abc”对象放入Pool,接着执行new String("abc");在堆中创建一个内容为"abc"的对象。共创建了两个对象,一个在池内,一个在堆中。s指向堆中的对象。
执行第二条语句:在Pool中找“abc"对象,由于第一条语句已经在Pool中创建了一个”abc",则返回“abc"的地址。共创建了0个对象。s1指向Pool中的对象。
执行第三条语句:此时Pool中有"abc”,则只会在堆中创建一个内容为"abc"的对象。共创建了1个对象。s2指向堆中的对象。
System.out.println(s==s1); // false,在Java中,“==”比较的是内存地址,也就是判断s和s1是否指向同一对象;
System.out.println(s.equals(s1)); // true,equals比较的是字符串的值。
System.out.println(s.intern()==s2.intern()); // true
System.out.println(s==s.intern()); // false
当调用intern()时,会在Pool中检查是否有值为“abc"的对象,若有,则翻译该对象的引用;若无,则在Pool中创建一个"abc”对象,并返回其引用。
String s,t; 其中s.intern()==t.intern()为true当且仅当s.equals(t)为true。
二、区分以下输出结果:
// true,"hel"和"lo“都是字面值(常量),用"+"连接后仍为字面值"hello”,此时,若Pool中没有"hello,则会在Pool中创建一个"hello"对象。返回Pool中对象的地址。String hello = "hello";
String hel = "hel";
String lo = "lo";
System.out.println(hello == "hel"+"lo");
// false,lo是池中的一个对象,不是字面值,则"hel“+lo会在堆中创建一个新的值为"hello”的对象,而hello是在池中的对象。System.out.println(hello == "hel"+lo);