为什么字符串不需要新关键字

2022-09-01 07:41:25

我是Java的新手。

在 java 中,是一个 .但是我们不必使用关键字来创建类的对象,其中 as 用于为其他类创建对象。StringclassnewStringnew

我听说过像这样的 Wrapper 类,它们与此类似。但包裹不是包装器,不是吗?IntegerDoubleString

实际上,当我使用时发生了什么

     String message = "Hai";

??它与

String message = new String("Hai");

这是一个参考变量或其他东西??还有其他不需要创建对象的类吗?messagenew


答案 1

使用以下行,您不是在堆中创建新对象,而是重用字符串文本(如果已经可用):String

String message = "Hai";

"Hai"是字符串文本池中的字符串文本。由于字符串是不可变的,因此它们是可重用的,因此它们由 JVM 池化到字符串文本池中。这是推荐的方式,因为您正在重用它。

但是,通过以下操作,您实际上是在创建一个新对象(在堆中):

String message = new String("Hai");

new String("Hai")是一个新对象。在这种情况下,即使文本已在字符串文本池中,也会创建一个新对象。不建议这样做,因为您可能会以多个具有相同值的对象结尾。String"Hai"String

另请参阅此帖子: 有关 Java 字符串池的问题

是否有其他类不需要新的来创建对象?

实际上,如果不使用关键字,则无法在Java中创建任何对象。new

例如:

Integer i = 1;

确实如此,并不意味着在不使用 的情况下创建对象。我们只是不需要明确使用关键字。但是在引擎盖下,如果值为 1 的对象在缓存中尚不存在(对象由 JVM 缓存),则将使用关键字来创建它。IntegernewnewIntegerIntegernew


答案 2

Java 语言规范允许将字符串表示为文本。您可以将其视为 String 的快捷方式初始化,该字符串具有一个重要的副作用,该副作用不同于通过 new 进行常规初始化

字符串文本全部被暂存,这意味着它们是 Java 运行时存储的常量值,可以在多个类之间共享。例如:

class MainClass (
    public String test = "hello";
}

class OtherClass {
   public String another = "hello";

   public OtherClass() {
       MainClass main = new MainClass();
       System.out.println(main.test == another);
   }
}

将打印出“true”,因为两个 String 实例实际上都指向同一个对象。如果通过 new 关键字初始化字符串,则不会出现这种情况。