码迷,mamicode.com
首页 > 编程语言 > 详细

java中String类intern()方法探索

时间:2017-11-08 20:01:51      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:重点   理解   问题   ==   最新   inter   intern   int   实例   

想到什么写什么,会有点乱,意思理解就行

首先我们创建两个字符串对象,如下:

String a = new String("hx");
String b = new String("h")+new String("x");

通过new关键字创建字符串对象时,会同时在堆和常量池中生成两个对象,比如说上面的第一条语句产生两个内容均为"hx"的对象,一个在堆中,一个在常量池中,a引用的是堆中的对象,内容是"hx";上面第二条语句产生五个对象,其中两个匿名对象的内容分别是"h"和"x",对应的,常量池中也会生成两个对象,内容分别是"h"和"x",还有一个对象是b引用的,在堆中,内容是"hx";

还有一种创建字符串对象的方法,就是直接赋值,如下:

String c = "hx";

这里,c引用的对象直接放在了常量池中

(常量池中内容相同的字符串对象,地址一定是相同的,而堆中不同的对象,地址一定不同)

理解上面的内容,然后继续往下看。

String类中intern()方法其实也是一个对象的引用(个人理解),引用的对象在常量池中

比如先通过new关键字创建字符串对象String s = new String("hx"),变量s引用这个对象,s.intern()方法就是检查常量池中有没有一个内容相同的对象

(这里是有的,因为之前说过,通过new关键字会同时创建两个内容相同的对象,一个在堆中,一个在常量池中),

若有,则s.intern()引用那个对象,此时(s == s.intern())是false,因为s和s.intern()引用的是两个不同的对象,只是内容相同,地址不同,自然不可能相等;

若没有(这种情况我也可以举个例子,String s = new String("h")+new String("x") ,此时常量池中只有两个内容分别为"h"和"x"的对象),则会在常量池中创建一个对象的引用,指向s引用的那个对象(这也是jdk1.7及以后版本与jdk1.6及以前版本的差别,我只探讨最新版本,不多说),说白了就是调用s.intern()方法后,在常量池中出现了一个引用,引用堆中s引用的那个对象(相当于绕了个圈,节省了内存,但时间开销更大),此时(s.intern() ==  s)是true,理由是两者引用的是同一个对象,地址相同,若此时出现这样一条语句String m ="hx",那么(m == s)或者(m == s.intern())就都是true了,因为两者引用了同一个对象,之前说过,常量池中内容相同的对象,地址一定相同,因为之前s.intern()首先在常量池中占了个坑,以后常量池中内容为"hx"的都是引用s.intern()引用的那个对象。

下面通过实例说话

String a = new String("hx");
System.out.println("1."+(a==a.intern()));

false

String a = new String("h")+new String("x");
a.intern();
String b = "hx";
System.out.println("2."+(a==a.intern()));
System.out.println("3."+(b==a));
 

true

true

String a = new String("hx");
a.intern();
String b ="hx";
System.out.println("4."+(a==b));
System.out.println("5."+(b==a.intern()));

false

true

String a = new String("hx");
String b = "hx";
a.intern();
System.out.println("6."+(a==a.intern()));
System.out.println("7."+(b==a.intern()));

false

true

是否有些头绪了?总之常量池中内容相同的,地址一定相同,谁第一个占坑了(两种占坑方式:intern()方法和直接声明常量,例如String t = "abc"),以后和它内容相同的都引用这个坑没差,重点要理解intern()方法引用的是哪个对象,地址在堆中还是在常量池中,还有一点,intern()方法一定是引用某个对象,绝不会自己创建一个对象然后引用的。

最后还有两种情况

String a = "h";
String b = "hx" String c = a+"x"; System.out.println(b==c);

结果是false

但如果改一下子,第一条语句加个关键字final

final String a = "h";
    String b = "hx";
    String c = a+"x";
    System.out.println(b==c);

结果是true

以下纯属个人理解:

首先出现这种情况无非就是引用的对象不相同,那第一种情况就是,b引用的对象在常量池中,c引用的对象在堆中;

第二种情况是,b和c引用的对象为同一个,均在常量池中。

就是final的问题,有这个关键字时,String c = a + "x";在编译时就那啥(描述不来,凑合着理解理解)产生了一个常量放在常量池中,然后发现已经有一个内容相同的了,就直接引用那个的了;没有这个关键字时,String c = a+"x"在运行时才产生结果,这个结果就只能是一个对象了,放在堆中,无法放入常量池中,因为常量池的内容在编译后就确定了,所以c == a自然就是false;

然后还有就是为什么一个在编译时就产生结果,一个就在运行时才能产生结果,这得问问final这个关键字了,我也不是很懂..

 

java中String类intern()方法探索

标签:重点   理解   问题   ==   最新   inter   intern   int   实例   

原文地址:http://www.cnblogs.com/huangxun/p/7805237.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!