字符串是程序中使用频率最高的一种数据类型,Java为了加强程序的运行速度,因此设计了两种不同的方法来生成字符串对象。一种是调用String类的构造函数,另一种是使用“”。这两种方法产生的字符串对象在内存中存放的机制不同: (1)在使用String构造函数定义字符串对象时,Java环境会和创建其他类型的对象一样,每次调用,都会创建一个新的对象。 (2)Java为String类型提供了缓冲池机制,当使用双引号定义对象时,Java环境首先去缓冲池寻找相同内容的字符串,如果存在就直接拿出来使用,如果不存在则创建一个新的字符串放入缓冲池中。 上面的两种机制分别对应字符串的存储形式为堆存储和常量池存储。可以看下面的例子: 另外,堆存储可以转换为常量池存储,是通过String类的intern()方法实现的。Intern方法的了解可以看JDK的描述,讲解的非常透彻: A pool of strings, initially empty, is maintained privately by the class String. When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned. It follows that for any two strings s and t, s.intern()==t.intern() is true if and only if s.equals(t) is true. All literal strings and string-valued constant expressions are interned. 我对上面的英文进行了翻译,译文如下: 当调用intern 方法时,如果池中已经包含一个等于此String 对象的字符串(是否相等由 equals(Object)方法确定),则返回池中的字符串引用。否则,将此 String 对象添加到池中,并且返回此String 对象的引用。例如:对于任何两个字符串s和t,当且仅当s.equals(t)为true时,s.intern()==t.intern()才为true。 所有字面值字符串和字符串赋值常量表达式都是intern实现的。 最后列出下面的例子说明了堆存储和常亮池存储的区别: |
|