序
前几篇文章一直在研究 WEB 安全的问题,而且最近工作中也一直在解决这些安全漏洞,当然,后续的博客中还会就这些暴露出来的问题谈谈我的解决方案,只不过,在这篇博客中,我想谈点别的问题,而且对于我们开发者来说,是一个老生常谈的问题。
简介
关于 String 类,我想大家一定不陌生,毕竟每天都打交道,早已经滚瓜烂熟了。我今天要说的不是整个 String 类,而是其中的一个方法,这个方法或许你都没有听说过,当然更别提用过了。废话不多说,进入正题。。。
正文
相信绝大多数的人不会去用 String 类的 intern() 方法,打开String类的源码发现这是一个本地方法,定义如下:
public native String intern();
该方法返回一个字符串对象的内部化引用。
String 类维护一个初始为空的字符串的对象池,当 intern() 方法被调用时,如果对象池中已经包含这一个相等的字符串对象则返回对象池中的实例,否则添加字符串到对象池并返回该字符串的引用。
我们在 new 一个 String 对象的时候,新产生的 String 在堆中,而不在字符串池中,即 CONSTANT_String_info 中。而 intern() 方法是到字符串池中查找是否存在该内容为指定字符串的 String 对象,如果有,则返回一个已有的引用,否则,创建在字符串池中创建新的引用,并返回该引用。
而采用 new 创建的字符串对象不进入字符串池,字符串相加的时候,都是静态字符串的结果会添加到字符串池,如果其中含有变量不会进入字符串池中。但是字符串一旦进入字符串池中,就会先查找池中有无此对象。如果有此对象,则让对象引用指向此对象。如果无此对象,则先创建此对象,再让对象引用指向此对象。
例子
Java语言规范中定义了字符串文字以及更一般的常量表达式的值的字符串是被内部化的,以便它们共享同一个实例。我们试验一下下面的代码:
String s1="你好,Java";
String s2="你好,"+"Java";
System.out.println(s1==s2);
System.out.println(s1.intern()==s2.intern());
这段代码将打印两个 true ,也就是说字符串 s1 和 s2 是共享同一个实例。不过前提是尽管使用了表达式,但是表达式中必须都是常量。
了解这个处理机制也可以让我们在用到字符串常量的时候了解如何节省这些字符串所占用的内存。
结束语
最后,推荐一篇关于 String 类的文章,建议大家有时间去看一下,感觉很有帮助的,尤其是对正在面试或将要面试的童鞋们。