String字符常量池和intern()的用法
计算机交流平台:计算机故障
_
计算机论坛
www.it168bbs.com?
?
wy?
?
[java]?
String?s3?=?new?String(newchar[]?{'a',?'b'});?
?
System.out.println(s3?==?s3.intern());?
?
//?true
:
s3
放入了常量池
?
?
?
?
?
//?------------------?
?
?
?
?
String?s3?=?new?String("ab");?
?
System.out.println(s3?==?s3.intern());?//?false
:
”ab”
放入了常量池
?
?
String?s3?=?new?String(newchar[]?{'a',?'b'});?
System.out.println(s3?==?s3.intern());?
?
//?true
:
s3
放入了常量池
?
//?------------------?
String?s3?=?new?String("ab");?
System.out.println(s3?==?s3.intern());?//?false
:
”ab”
放入了常量池
?
?
?
?
?
上面的两个校验操作返回的结果不一样,第一种情况,
s3.intern()
的时候,常量池还没有
"ab"
,所以
s3
的地址被插入到了常量池,所以
s3
和
s3.intern()
是指向同一个地方的。
?
?
?
?
?
而第二种情况,
"ab"
在编译时就插入常量池了,所以
s3.intern()
指向的是常量池的
"ab"
,
而不是
s3
本身,所以
s3
和
s3.intern()
不相等。
?
?
?
2
、常量和
new?String?
[java]?
String?s1?=?"ab";?
?
?
?
?
//?
编译期会把
"ab"
添加到常量池
?
?
?
?
?
String?s2?=?new?String("ab");?
?
//?
只是
"ab"
从常量池取,而
new
又重新创建了一个
String?
?
?
?
?
System.out.println(s1?==s2);?
?
//?false
:两个不同的对象,返回
?
?
?
?
?
System.out.println(s1.intern()==?s2);?
?
//?false
:
s1?
等价于
?
s1.intern()?
?
?
?
?
System.out.println(s1?==s2.intern());?//?true
:
intern
会到常量池中查找
?
?
String?s1?=?"ab";?
?
?
?
?
//?
编译期会把
"ab"
添加到常量池
?
String?s2?=?new?String("ab");?
?
//?
只是
"ab"
从常量池取,而
new
又重新创建了一个
String?
System.out.println(s1?==s2);?
?
//?false
:两个不同的对象,返回
?
System.out.println(s1.intern()==?s2);?
?
//?false
:
s1?
等价于
?
s1.intern()?
System.out.println(s1?==s2.intern());?//?true
:
intern
会到常量池中查找
?
?
?
?
?
运行期间,
s1
直接指向常量池的
"ab"
,而
s2
用
new
创建,相当于先从常量池拿出
"ab"
,
然后再创建一个
String
。
?
?
?
?
?
所以
s1
和
s2
是两个对象;
s1.intern()
和
s1
都是指向常量池,
所以两者等价。
而
s2.intern()
也是从常量池中获取,所以
s1?==?s2.intern()
。
?
?
?
?
?
总结:字符串常量池是
JVM
为了缓存我们用过的字符常量,避免重复创建字符对象,
来提高效率。但是遇到一些特殊情况,如字符串相加操作,往往会产生很多多余无用的字符
常量,这个处理方式就值得商榷了。