原因:

字符串a=Hello World!;

字符串b=Hello World!;

a=b?

a 和 b 相等吗?为什么?

String a=new String(Hello World!);

String b=Hello World!;

a=b?

a 和 b 相等吗?为什么?

说明:

1.
首先,String不属于8种基本数据类型。字符串是一个对象。

因为对象的默认值是null,所以String的默认值也是null;但它是一种特殊的物体,具有一些其他物体所不具备的特征。

2. new String()和new String("")都声明了一个新的空字符串,它是一个空字符串,不为null;

3.
String str=kvill;

String str=new String(“kvill”);的区别:

这里我们不说堆,也不说栈,首先简单介绍一下常量池的简单概念。

常量池(constant pool)是指编译时确定并保存在编译池中的池。

类文件中的一些数据。它包括类、方法、接口等中的常量,以及字符串常量。

看示例1:

String s0=kvill;

String s1=kvill;

String s2=kv + ill;

系统。
出来了。 println( s0==s1 );

System.出去。 println( s0==s2 );

结果是:

true

true

首先,我们需要知道Java会确保一个字符串常量只有一份副本。

因为示例中s0和s1中的“kvill”都是字符串常量,在编译时就确定了,所以

s0==s1为true; “kv”和“ill”也是字符串常量。当一个字符串是由多个字符串常量组成时,它本身必然是一个字符串常量,所以 s2 也在编译时被解析为字符串常量,所以 s2 也是常量池“kvill”中的一个引用。
所以我们得出结论 s0==s1==s2;

用new String()创建的字符串不是常量,无法在编译时确定,所以new String( )

创建的字符串不会放入常量池,它们有自己的地址空间。

参见示例2:

String s0 =kvill;

String s1=new String(kvill);

String s2=kv+ new String(ill);

System.
出。 println( s0= =s1 );

System.out.println( s0==s2 );

System.out.println( s1==s2 );

结果是:

false

false

false

在示例2中,s0仍然是“kvill”的应用在常量池中,而 s1 无法在编译时确定,因此它是对运行时创建的新对象“kvill”的引用。由于s2有new String的后半部分(“ill”),无法编译

< p>周期确定,所以也是新创建的对象“kvill”的应用;如果你明白了这一点,你就会知道为什么会得到这个结果。

4. String.intern():

还有一点:.class文件中存在的常量池是在运行时由JVM加载的,可以扩展。时间String的intern()方法是扩充常量池的方法;当一个String实例str调用intern()方法时,Java会检查常量池中是否存在具有相同Unicode的字符串常量。如果是,则返回其引用。如果没有,则在常量池中添加一个 Unicode 等于 str 的字符串并返回其引用。引用;为清楚起见,请参阅示例 3。

示例 3:

String s0= kvill;

String s1=new String(kvill);

String s2=new String(kvill);

System.out.println( s0==s1 );

System.
out.println (“************”);

s1.intern();

s2=s2.intern(); //将常量池中kvill的引用赋值给s2

System.出去。 println(s0==s1);

System.出去。
println( s0==s1.intern() );

系统。出去。 println( s0==s2 );

结果为:

false

************

false //虽然s1执行了。 intern(),但其返回值并未赋值给s1

true //解释s1。
实习生()返回常量池中“kvill”的引用

true

最后我再澄清一个误解:

有人说,“使用String.intern ()方法,可以将一个String类保存到一个全局String

g表中,如果这个表中已经存在相同值的Unicode字符串,那么这个方法返回已经有该字符串的地址如果表中没有同值的字符串,就在表中注册自己的地址。”如果我理解全局的String表他说的是常量池,他最后一句话,“如果有的话表中没有相同值的字符串,请在表中注册自己的地址”是错误的:

看示例4:

String s1= new String(kvill);< /p>

字符串 s2=s1。
实习生();

系统。出去。 println( s1==s1.intern() );

System.出去。 println( s1+ +s2 );

System.出去。 println( s2==s1.intern() );

结果:

false

kvill kvill

true

在这个类中我们没有声明kvill 常数,所以 s1。
当我们调用 s1 时,intern() 与 new String(kvill) 不同。 intern()之后,一个新的kvill常量被添加到常量池中。原来不在常量池中的kvill仍然存在,这意味着它不再是“在常量池中注册自己的地址”。

s1==s1。
intern()为false,说明原来的“kvill”仍然存在;

s2现在是一个常量池中“kvill”的地址,所以s2==s1。实习生()是真的。