java字符串中的intern方法是什么概念?
首先,字符串不属于八种基本数据类型,字符串是一个对象。
因为object的默认值是null,所以String的默认值也是null;但它是一个特殊的物体,具有一些其他物体所没有的特性。
2.
new String()和new String(" ")都声明了一个新的空字符串,该空字符串不为null;
3.
String str = " kvill
线
str =新字符串(" kvill ");区别在于:
这里不谈堆或者栈,只是简单介绍一下常量池这个简单的概念。
常量池(常量
Pool)指的是在编译时确定并保存在编译后的。类文件。它包括关于类、方法、接口等的常量。,以及字符串常量。
参见示例1:
线
s0 = " kvill
线
s 1 = " kvill ";
线
S2 =“kv”+“生病”;
System.out.println(
s0 = = s 1);
System.out.println(
s0 = = S2);
结果如下:
真实的
真实的
首先,我们需要知道Java将确保一个字符串常量只有一个副本。
S0 = = s1为真;因为S1中的S0和“kvill”都是字符串常量,是在编译时确定的。而“kv”和“ill”也是字符串常量。当一个字符串由多个字符串常量连接时,它本身必须是一个字符串常量,所以s2在编译时也被解析为一个字符串常量,所以s2也在常量池中。
对“kvill”的引用。
所以我们得到s0 = = s 1 = = S2;
使用新的
string()创建的字符串不是常量,不能在编译时确定,所以new String()创建的字符串不放入常量池,它们有自己的地址空间。
参见示例2:
线
s0 = " kvill
线
s 1 =新字符串(" kvill ");
线
s2="kv" +新串(" ill ");
System.out.println(
s0 = = s 1);
System.out.println(
s0 = = S2);
System.out.println(
s 1 = = S2);
结果如下:
错误的
错误的
错误的
例2中,s0仍然是常量池中“kvill”的应用,s1是对运行时创建的新对象“kvill”的引用,因为在编译时无法确定,s2有new的后半部分。
string(“ill”)在编译时无法确定,所以它也是一个新创建的对象“kvill”的应用;了解这些你就知道为什么会得出这个结果了。
4.
String.intern():
还有一点:中的常量池。类文件由JVM在运行时加载,并且可以扩展。String的intern()方法是一个扩展常量池的方法。当一个字符串实例str调用intern()方法时,Java在常量池中查找是否有Unicode相同的字符串常量,如果有,则返回其引用;如果不是,则在常量池中添加一个Unicode等于str的字符串,并返回其引用;为清楚起见,参见实施例3。
示例3:
线
s0 = " kvill
线
s 1 =新字符串(" kvill ");
线
s2 =新字符串(" kvill ");
System.out.println(
s0 = = s 1);
System.out.println(
"**********" );
s 1 . intern();
S2 = S2 . intern();
//将常量池中“kvill”的引用赋给s2。
System.out.println(
s0 = = s 1);
System.out.println(
s0 = = s 1 . intern());
System.out.println(
s0 = = S2);
结果如下:
错误的
**********
错误的
//虽然执行了s1.intern(),但其返回值并没有赋给s1。
真实的
//描述:s1.intern()返回常量池中对“kvill”的引用。
真实的
最后,我要打破一个错误的认识:
有人说,“使用String.intern()方法,可以将一个字符串类保存到全局字符串表中。如果该表中已经存在具有相同值的Unicode字符串,则该方法返回表中现有字符串的地址。如果表中没有相同值的字符串,则在表中注册您的地址。”他说,如果我把这个全局字符串,
如果把字符串表理解为常量池,他最后一句“如果表中没有相同值的字符串,就在表中注册你的地址”是错的:
参见示例4:
线
s 1 =新字符串(" kvill ");
线
S2 = s 1 . intern();
System.out.println(
s 1 = = s 1 . intern());
System.out.println(
s 1+" "+S2);
System.out.println(
S2 = = s 1 . intern();
结果:
错误的
克维尔
克维尔
真实的
我们在这个类中没有命名一个“kvill”常量,所以一开始常量池中没有“kvill”。我们在调用s1.intern()时,在常量池中增加了一个新的“kvill”常量,原来不在常量池中的“kvill”仍然存在,这并不是“在常量池中注册你的地址”。
S1==s1.intern()为false,表示原来的“kvill”仍然存在;
S2现在是常量池中“kvill”的地址,所以s2==s1.intern()为真。
5.
On equals()和= =:
对于String来说,这只是简单的比较两个字符串的Unicode序列是否等价,如果相等则返回true而= =是比较两个字符串的地址是否相同,即是否是对同一个字符串的引用。
6.
关于字符串是不可变的。
这个有很多话要说,只要知道String的实例一旦生成,就不会改变,比如:String。
str = " kv "+" ill "+" "+" ans ";
有四个字符串常量。首先,“kv”和“ill”生成“kvill”,然后“kvill”与“
在内存中生成“kvill”,最后用。
ans”;并且将这个字符串的地址赋给str,因为String的“不变性”产生了很多临时变量,这也是为什么建议使用StringBuffer的原因,因为StringBuffer是可变的。