关于String直接赋值和new的一些理解

#关于字符串常量池的概念想必大家都懂,今天主要围绕String对象来谈谈我的理解。
首先先给大家看一段代码

String s1="abc";
String s2=s1+"def";
String s3=s1+"def";
System.out.println(s2==s3);

让我们先来猜下这段代码的输出结果是什么?
在这里插入图片描述
答案既然是false!

我们都知道字符串常量池中一个字符串是唯一的,如果s2和s3指向的是字符串常量池中的字符串,那么我们的输出结果应该是true,而我们输出的结果是false,所以s2和s3并不是简单的指向字符串常量池中的数据。
我们知道String并不是基本的数据类型,它有两种创建方式:①字面量定义的方式:String str=“abc”;②new:String str=new String(“abc”);
第一种方式只是在栈空间开辟了一个空间存放str,然后在字符串常量池中存储了"abc";第二种方式则是在堆空间开辟了一个对象,在栈空间存放了一个变量str,该变量指向堆空间的对象,然后该对象指向了字符串常量池中对应的字符串,下面我们举个例子来证明一下我们的观点

class Person{
    String name;

    public Person(String name) {
        this.name = name;
    }
}
public class StringTest{
    public static void main(String[] args) {
        Person p1=new Person("tom");
        Person p2=new Person("tom");
        System.out.println(p1.name == p2.name);
    }
}

在这里插入图片描述
由此验证了我们的观点。
回到我们最初的话题,既然我们的输出结果为false,s2和s3指向的肯定不是同一个地址,有的同学就会问了,它们指向的不都是s1+"def"这个字符串吗,事实并非如此。当字符串拼接时,如果其中一个是变量(比如我们这里的s1),那么JVM就会在堆空间new一个String类的对象,用来存放字符串对象,然后该对象指向字符串常量池中对应的字符串数据。即我们的s2,s3指向的是堆中的对象,所以得到的结果当然是false。

发布了3 篇原创文章 · 获赞 1 · 访问量 60

猜你喜欢

转载自blog.csdn.net/dlhlzxw/article/details/104025565