String s1 = new String(“abc“);这句话创建了几个字符串对象?

在Java中,String s1 = new String("abc"); 这句代码实际上创建了两个字符串对象,尽管从表面上看它似乎只创建了一个。

  1. 字面量字符串 "abc"
    • 当JVM在代码中遇到字符串字面量 "abc" 时,它首先会检查字符串常量池中是否已经存在内容为 "abc" 的字符串对象。
    • 如果不存在,JVM会在字符串常量池中创建一个新的字符串对象,内容为 "abc",并返回该对象的引用(但实际上,在这行代码执行之前,我们并没有直接使用这个引用)。
    • 如果已经存在,JVM则不会创建新的对象,而是直接返回常量池中已存在对象的引用。但在这个特定的情况下,由于这是第一次出现 "abc",所以会在常量池中创建一个新的对象。
  2. 通过 new 关键字创建的字符串对象
    • new String("abc") 会在堆内存中创建一个新的 String 对象。这个新创建的 String 对象的内部会包含对字符串常量池中 "abc" 字符串对象的引用(或者是其内容的副本,具体取决于JVM的实现,但在大多数情况下,为了节省内存,会是对常量池中对象的引用)。
    • 重要的是要理解,尽管这个新创建的 String 对象的内容与常量池中的 "abc" 相同,但它们是两个不同的对象,分别存储在堆内存和常量池中。

因此,String s1 = new String("abc"); 这句话实际上创建了两个对象:一个在字符串常量池中(如果它之前不存在的话),另一个在堆内存中。s1 变量引用的是堆内存中的那个 String 对象。


	public class StringExample { 

	public static void main(String[] args) { 

	String s1 = new String("abc"); 

	} 

	}

 对应的字节码:

public static void main(java.lang.String[]);  
  Code:  
       0: ldc           #2                  // String abc  
       2: invokespecial #3                  // Method java/lang/String."<init>":(Ljava/lang/String;)V  
       5: astore_1  
       6: return

分析字节码指令:

  1. 0: ldc #2 // String abc
    • 这条指令将字符串常量池中的"abc"字符串的引用推送到操作数栈上。如果"abc"之前不在常量池中,JVM会在这一刻将其添加到常量池中。但请注意,ldc指令本身并不在字节码层面“创建”对象;它只是引用了一个已经存在(或即将被创建)的常量池条目。
  2. 2: invokespecial #3 // Method java/lang/String."<init>":(Ljava/lang/String;)V
    • 这条指令调用了String类的构造函数,该构造函数接受一个字符串参数(在这个例子中,是操作数栈顶部的"abc"字符串的引用)。这导致在堆上创建了一个新的String对象,该对象的内容与常量池中的"abc"相同,但它们是两个不同的对象。
  3. 5: astore_1
    • 这条指令将操作数栈顶部的引用(即新创建的String对象的引用)存储到局部变量表的第一个槽位中,该槽位对应于s1变量。
  4. 6: return
    • 这条指令表示方法结束并返回。

        虽然字节码本身不直接说明“创建了两个对象”,但通过分析我们可以推断出,在执行String s1 = new String("abc");时,JVM首先(在需要时)在字符串常量池中创建或引用了一个"abc"字符串对象,然后在堆内存中创建了一个新的String对象,其内容引用(或复制自,取决于JVM实现)常量池中的"abc"字符串。因此,从逻辑上讲,这句话确实创建了两个字符串对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值