string.intern()那些事
参考自 :http://blog.youkuaiyun.com/seu_calvin/article/details/52291082,这篇关于运行时常量池的位置有些偏差,运行时常量池是在方法区中的,主要用于存放编译器生成的各种字面量和符号引用。
最近在看java虚拟机的一些,遇到频繁出现的词:string.intern();经常会说intern()是一个native方法。(下面代码的基于JDK1.7)
解释两个点:
1.什么是Native方法。
2.intern()是能做什么的,有什么用。
1.什么是Native方法。
Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。
2.intern()能做什么的,有什么用。
intern()在jdk中是这样描述的:
public String intern()返回字符串对象的规范化表示形式。
当一个字符串对象在调用intern()时,进行判断:判断该字符串对象在常量池是否已经存在{
1.已经存在,则返回该字符串;
2.如果不存在,则将该字符串加载进常量池,并返回该字符串对象的引用(注意加载进常量池的字符串的引用仍然是之前对象的引用);
}
代码1:
//String o = "abc";
String a = new String("a") + new String("bc");
a.intern();
String b = "abc";
System.out.println(a==b);//true
程序是这样运行的:加载字符串a时,不会在常量池中创建abc,在加载a.intern();因为abc在常量池中不存在,所以会将abc加载进常量池,并且返回的是a对象的引用,加载b时,因为常量池中已经存在abc,所以指向了abc的地址(其实是指向a的地址),所以输出为true。
当我们打开第一行的注释时,输出为false。
代码2:
String a = new String("abc");
a.intern();
String b = "abc";
System.out.println(a==b);//false
System.out.println(a.intern()==b);//true
在new String("abc")会创建两个对象,在堆中创建一个,在常量池中创建abc字符串,当a.intern()时,因为常量池中已经存在abc对象,则返回的是该字符串。所以a.intern()==b为true。
代码3
这是打开注释第一段代码
String o = "abc";
String a = new String("a") + new String("bc");
a.intern();
String b = "abc";
System.out.println(a==b);//false
在第一行已经将abc加载进常量池,所以a.intern();返回的仅仅是abc这个字符串,而加载b时指向的是常量池中abc字符串,所以结果会和代码1中的结果有区别。
画了一张图来描述: