字符串是程序中使用频率最高的一种数据类型,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.
我对上面的英文进行了翻译,译文如下:
字符串常量池,初始值为空,它由类String类独自维护。
当调用intern 方法时,如果池中已经包含一个等于此String 对象的字符串(是否相等由 equals(Object)方法确定),则返回池中的字符串引用。否则,将此 String 对象添加到池中,并且返回此String 对象的引用。例如:对于任何两个字符串s和t,当且仅当s.equals(t)为true时,s.intern()==t.intern()才为true。
所有字面值字符串和字符串赋值常量表达式都是intern实现的。
最后列出下面的例子说明了堆存储和常亮池存储的区别:
写技术文章不容易,写一篇通俗易懂,雅俗共赏的技术文章更难,希望一时的热度变成长久的坚持,希望获得大家的认可。欢迎大家关注【Java人生】。关注Java,关注人生。关注Java的魅力,关注人生的多彩!