为什么String不需要新的关键字

我是java的新手。

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

我听说过类似于IntegerDouble Wrapper类。 但String不是Wrapper,不是吗?

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

  String message = "Hai"; 

?? 它有什么不同

 String message = new String("Hai"); 

这是message引用变量还是其他什么? 还有其他类不需要new来创建对象吗?

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

 String message = "Hai"; 

"Hai"是字符串文字池中的字符串文字。 因为,字符串是不可变的,所以它们是可重用的,因此它们由JVM汇集在字符串文字池中。 这是推荐的方式,因为您正在重复使用它。

但是,通过以下内容,您实际上是在堆中创建一个新对象:

 String message = new String("Hai"); 

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

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

还有其他类不需要new来创建对象吗?

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

例如

 Integer i = 1; 

是否,并不意味着在不使用new情况下创建Integer对象。 我们不需要明确使用new关键字。 但在幕后,如果缓存中不存在值为1的Integer对象( Integer对象由JVM缓存),则将使用new关键字来创建它。

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关键字初始化字符串,则情况并非如此。

字符串和整数创建是不同的。

 String s = "Test"; 

这里’=’运算符为字符串重载。 “一些”+“事物”中的“+”运算符也是如此。 在哪里,

 Integer i = 2; 

直到Java 5.0这是编译时错误; 你不能将原语分配给它的包装器。 但是从Java 5.0开始,这称为自动装箱,其中原语会在需要时自动提升到其包装器。

 String h1 = "hi"; 

会有所不同

 String h2 = new String("hi"); 

原因是JVM维护所有字符串文字的字符串表。 所以表中会有一个“hi”的条目,比如它的地址是1000。

但是当您显式创建一个字符串对象时,将创建一个新对象,比如它的地址是2000.现在新对象将指向字符串表中的条目1000。

因此,当你说

 h1 == h2 

它比较

 1000 == 2000 

所以这是错误的

在java中
“==”比较左侧和右侧的内存位置(而不是该内存位置的值),因此在情况下

new String("hai")==new String("hai")

它返回false。

在“Hai”==“Hai”的情况下,java不为相同的字符串文字分配单独的内存,因此这里“==”返回true。 您始终可以使用equals方法来比较值。