Java中String类的两种定义方式
前言
这里将讨论字符串的两种定义方式的使用与区别以及“==”的各种判断
一、字符串有哪两种定义方式
1.String str1 = “123”;
String str1 = "123";
String str2 = "123";
在这里首先要了解一下这样子定义在内存中是什么样的。

栈中存贮对象的引用(保存着对象的地址值),字符串常量储存在方法区中。
方法区中不含相同的值,因此以此种方式定义的时候str1与str2中存放的地址值相同。
因此
@Test
public void test1(){
String str1 = "123";
String str2 = "123";
System.out.println(str1==str2);
}
打印结果为true。
2.String str1 = new String(“123”);
用“new+构造器”这种方式创建String对象new一次就在堆空间中开辟一个空间。
用这种方法创建对象在内存中会创建两个对象:一是堆空间中new结构,二是char[]对应的常量池中的数据。
在内存中的图示:

此时str1与str2储存的是堆中的地址,因此即使他们在方法区的值相同,他们的地址值也是不同的。
因此:
@Test
public void test2(){
String str1 = new String("123");
String str2 = new String("123");
System.out.println(str1==str2);
}
此时结果为false。
二、两种定义方式的不同
String str1 = new String("123");
String str2 = "123";
此时在内存中的位置:

用new定义则字符串对象存放在堆中,因此此时str1中储存的是堆空间的地址值。
因此
@Test
public void test3(){
String str1 = new String("123");
String str2 = "123";
System.out.println(str1==str2);
}
此时结果为false。
二种定义方式的不同:
1.字符串常量存储在字符串常量池,目的是共享。
2.字符串非常量值对象存储在堆中。
三、各种“==”的判断
@Test
public void test4(){
String s1 = "hello";
String s2 = "world";
String s3 = "hello" + "world";
String s4 = s1 + "world";
String s5 = s1 + s2;
String s6 = (s1 + s2).intern();
System.out.println(s3 == s4);//false
System.out.println(s3 == s5);//false
System.out.println(s4 == s5);//false
System.out.println(s3 == s6);//true
}
图示:

因此:
1.常量与常量的拼接结果在常量池。且常量池不会存在相同内容的常量。
2.只要其中一个是变量,结果就在堆中。
3.如果拼接的结果调用intern()方法,返回值就在常量池中。
本文探讨了Java中String类的两种定义方式及其在内存中的表现形式,详细解析了使用直接赋值和new关键字创建字符串的区别,以及如何通过==运算符进行比较。文章还深入分析了字符串拼接和intern()方法的使用场景。

5843

被折叠的 条评论
为什么被折叠?



