偶然碰到一个关于String对象调用intern()方法的问题,在此作一下回顾总结:
1、String是不可变对象,其底层维护一个final型的字符串数组。
private final char value[];
这也就是为什么在需要进行大量的字符串拼接的地方,都建议不要使用"+"拼接,每次都会重新重新构造一个String对象
大量的此操作会太消耗内存。可以使用StringBulider构造一个对象,然后使用append方法添加字符串,达到拼接字符串的目的。
2、String中对象的比较,"=="和equals的使用:
"=="比较的是String对象的地址是否相同,而equals比较的是String对象的内容,即字符串的内容是否一致。
String str1 = "hello";
String str2 = "hello";
System.out.println(str1 == str2);
结果为true.jvm中存在一个字符串常量池,在初始化str1的时候,"hello"会被存放到字符串常量池中,然后在初始化str2的时候,
在常量池中找到"hello",str2也会指向这个"hello",所以str1和str2引用的同一个字符串对象。
String str1 = "hello";
String str2 = new String("hello");
System.out.println(str1 == str2);
结果为false,因为str2是重新new的对象,存放在堆上,所以str1和str2指向的是两个不同的对象。
String str1 = "hello";
string str2 = new String("hello");
System.out.println(str1 == str2.intern());
intern()方法,String源码中解释如下,当intern方法被调用时,会首先去字符串常量池中去查找是否包含与之相同字符串内容的
对象,如果存在则会返回此对象,反之则会把此对象加入到String pool中
*
* When the intern method is invoked, if the pool already contains a
* string equal to this {@code String} object as determined by
* the {@link #equals(Object)} method, then the string from the pool is
* returned. Otherwise, this {@code String} object is added to the
* pool and a reference to this {@code String} object is returned.
*
上例子中,初始化str1时候,"hello"被加入到String pool中,str2调用intern方法,在String pool中查找到"hello",然后返回此对象,str1和str2都指向同一个对象,所以结果返回true;
String str1 = new String("hello");
System.out.println(str1 == str1.intern());
在初始化构造str1的时候,使用new在堆上创建一个对象。str1指向堆上的一个对象,而参数"hello"作为字符串常量被加入到String pool中,所以在str1调用intern的时候,在常量池查找到"hello"并返回,最后打印false。