黑马程序员技术交流社区

标题: 字符串中intern方法的返回值问题。 [打印本页]

作者: 曾祥旭    时间: 2013-3-27 11:30
标题: 字符串中intern方法的返回值问题。
本帖最后由 曾祥旭 于 2013-3-27 16:12 编辑

对于下面的程序:
String str1=new String("abc");
String str2=str1.intern();
System.out.println(str2);
str1的两个对象都是存储在堆内存当中的,当str1调用intern方法时,是不是
将堆内存对象"abc"存储到字符串池中,然后,str2引用该对象?有点小迷糊。
作者: 罗胜华    时间: 2013-3-27 11:40
我来回答你:
  String str1=new String("abc");
   这个string在内存中存储的情况: 所有引用数据都存在堆内存中,而堆内存中有一块区域是string缓冲池,如果池中没有abc这个字符串的话,这段代码就会先在堆内存中创建一个对象,然后再维护缓冲池。

当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串,   则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。

所以你写的这个String str2=str1.intern();   是把缓冲池中的abc赋值给了str2,所以你如果System.out.println(str1==str2);结果是false,因为所指向的地址不一样
能明白吗?

作者: 陈腾跃_2013    时间: 2013-3-27 11:44
当调用 intern 方法时,如果字符串池中已经包含一个等于此 String 对象的字符串,则返回池中的字符串。
否则,将此 String 对象添加到池中,并返回此 String 对象的引用。

字符串池中是否包含等于String对象的字符串使用equals(Object)确定.
作者: 黑马潘浩    时间: 2013-3-27 11:52
我的理解是这样的:String str1=new String("abc");内存里面生成2个对象,它们的内容分别都是abc,注意:str1不是对象,它是对象的地址,它叫做引用(reference),str指向new...生成的对象。换句话说,在java里面,当我们定义一个类的变量(如:String str;),它永远都是引用,不是对象。那么什么是对象呢?当我们用关键字new时,它生成出来的东西叫做对象。为什么是两个对象呢?首先它生成一个对象是abc,这个abc对象在什么地方呢?它在一个叫String Pool的字符串池里面,只有String有这样一个String池。String池是一个什么概念呢?我们知道,String类是一个不可变的类,一但它的内容确定,它就不能去更改了。当你去生成一个字符串对象的时候,它的执行流程是这样的:它首先在你的String Pool里面去找,看有没有一个内容为abc的对象存在,因为tring str = new String("abc")它是main方法的第一个语句,那么在刚开始执行的时候,String Pool里面是没有对象的。它发现String Pool里面没有abc这个对象,那么它首先把new String("abc")的括号里面的abc对象放到String Pool里面,接下来它执行new ...这行语句, 执行String的构造方法。我们知道new它生成一个对象,这个对象在什么地方呢?在java的堆里面。我们知道java的内存分为2部分,一个叫栈(Stack),一个叫堆(Heap)。那么new String("abc")时,它在堆(Heap)里面,生成一个内容为abc的这样一个对象。这样就造成了在String Pool里面一个叫abc的对象,堆里面也有一个叫abc的对象。
而String str2=str1.intern();查看API可以看到当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。
所以str2还是一个引用,它也指向了字符串"abc",所以你打印str2的时候还是打印"abc"。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2