【Java小知识】字符串String的理解

前言

String是我们接触和使用最多的,也是最基础的Java对象,相信大家都不陌生,我们先来看两个小问题:

1.new String(“abc”)创建了几个对象?
2.String s = “abc” ; String s1 = “ab” + “c”; System.out.println(s==s1);输出结果是什么?

所以答案是什么呢,见下分晓

字符串创建和存储的机制

字符串的初始化有两种情况:

  1. first

对于String s1 = new String(“abc”) 和String s2 = new String(“abc”)存在两个引用对象s1、s2,两个内容相同的字符串对象"abc",但它们在内存中的地址是不同的。所以只要用new总会生成新的对象。

  1. second

对于String s1 = "abc"和String s2 = “abc”,在JVM中存在着一个字符串池,其中保存着很多String对象,并且可以被共享使用,s1、s2引用的是同一个常量池中的对象。
由于String的实现采用了Flyweight的设计模式,当创建一个字符串常量时,会首先在字符串常量池中查找是否已经有相同的字符串被定义,采用equal()方法来判断。若已经定义,则直接获取对其的引用,此时不需要创建新的对象;若没有定义,则首先创建这个对象,然后把它加入到字符串池中,再将它的引用返回。

example:

String s1 = "abc";  //在常量区里面存放一个"abc"字符串对象
String s2 = "abc"; //s2引用常量区中对象,因此不会创建新的对象
String s3 = new String("abc"); //在堆中创建新的对象
String s4 = new String("abc"); //在堆中又创建了一个新的对象

为了方便理解,可以把String s = new String(“abc”)的执行人为的分为两个过程:

第一个过程是新建对象的过程,即new String(“abc”);
第二个过程是赋值的过程,即String s=。
由于第二个过程只是赋值过程,不会创建新的对象,所以只有第一个过程new String(“abc”)会调用String类的构造函数。

	public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

在调用构造函数时传入了一个字符串常量,因此new String(“abc”)也就等价于"abc"和new String()两个操作了。

若字符串池中不存在"abc",则会创建一个字符串常量"abc",并添加到字符串池中;
若存在,则不创建,然后new String()会在堆中创建一个新的对象。

在这里插入图片描述
从上面的分析可以回答上面两个问题
1、new String(“abc”)创建了几个对象?

答案:一个或两个。如果常量池中原来有"abc",那么只需要创建一个对象;如果没有,那么就会创建两个对象。

2、String s = “abc” ; String s1 = “ab” + “c”; System.out.println(s==s1);输出结果是什么?

答案:true。因为"ab"+“c"在编译器就被转换为"abc”,存放在常量区,因此s1和s2引用了同一对象。

引申思考:

String类型的变量s,赋值语句s == null与s= ""是否相同?

小结

String初始化存在两种方式,String s="abc"和String s = new String(“abc”),创建s对象时会先通过equal()方法判断字符串常量池内是否存在该对象。如果存在直接引用,不存在需要创建新的对象,同时new比如会创建一个新的对象。

发布了18 篇原创文章 · 获赞 38 · 访问量 692

猜你喜欢

转载自blog.csdn.net/wudingmei1023/article/details/103834628