先抛出问题和答案:
public static void main(String[] args) {
String s1 = "word";
System.out.println(s1.intern() == s1);//true
String s2 = new String("xx");
System.out.println(s2.intern() == s2);//false
String s3 = new String("jo") + new String("jj");
System.out.println(s3.intern() == s3);//true
String s4 = new String("ja") + new String("va");
System.out.println(s4.intern() == s4);//false
}
intern方法的定义
如果字符串常量池中有这个字符串,那么返回字符串常量池的地址,如果没有,创建一个对象,放入到字符串常量池中,返回这个对象的地址。
第一组
第一行 定义一个word字符串,如果有,直接返回地址,如果没有创建
第二行 根据intern的方法定义,也是返回常量池的地址,
故:true。
第二组
第一行:这一句首先会加载字符串xx,还是上面的,如果有直接返回地址,如果没有返回地址创建,然后这个,然后用到了new String,我们都知道对象都是存在堆里免得,这里也不意外,这个s2其实指向的是的堆里的String对象,
第二行: 因为xx的字符已经在常量池里面了,所以直接返回它的地址,用s2的对象地址 和 常量池里面的的地址比较。
故:false
第三组:
第一行:首先把"jo"和"jj" 加载进内存,然后进行拼接操作,拼接成"jojj",这时内存中有"jojj"吗?
显然是没有的,这时把"jojj"存入到常量池中,但是它并不是重新创建对象,而是把字符串的value对象直接指向堆里的new String("jojj"),但是字符串常量池中并没有这个对象,只有这个对象的引用。
注意:等号右面是创建五个对象,分别是"jo","jj"和它们对应的常量池对象,再加上拼接成的"jojj"
第二行:根据上面的定义,如果有直接返回地址,第一行已经替我们加载了
故:true;
第四组
第一行 :这就是java的关键字,是早已存在在常量池中的,在类加载的时候就被加载过了,虽然也创建了五个对象,但是s4 对应的对象里面的”java“是指向常量池中。
第二行: 拿早已经加载过的java 和 我们的对象比较
故:false