为什么String不需要新的关键字
我是java的新手。
在java中, String
是一个class
。但是我们不必使用new
关键字来创建类String
的对象,其中new
用于为其他类创建对象。
我听说过类似于Integer
, Double
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方法来比较值。