-2
String s ="hello";
String s= new String ("hello");
String s1= new String("hello");

在上述情况下如何在内部创建字符串对象。

String s = null;
String s = new String (null);  // I get a compilation error at this line

在上述情况下,我没有得到对象实例化。Java doc 说它创建了一个新的 obj / 使用原始参数作为字符串创建了一个新的 obj。

但我还是不清楚

4

6 回答 6

3

Java 使用享元设计模式来管理 JVM 中的 String 实例。简而言之,这种模式归结为共享可能有太多实例需要存储的对象。

String s ="hello";

在这里,JVM 首先检查字符串池是否已经存在“hello”。如果是,则s开始直接指向它。否则,首先将“hello”添加到池中,然后s指向它。

String s= new String ("hello");

在这里,字符串“hello”已经存在于字符串池中,但 new 的使用仍在继续,并在堆上创建了一个具有相同值“hello”的新字符串对象。

String s1= new String("hello");

和上面一样。我们现在有三个 String 对象。

String s = null;

在这里,您已经简单地将一个变量初始化为null. 这里没有什么特别的。

String s = new String (null);

这不起作用,因为 String 构造函数被重载。可能需要一个String; 它也可能需要一个char[]。但是当你传递它时,null编译器不知道要调用哪个构造函数,因为它没有任何数据类型可以进行匹配,因此它会给你一个模棱两可的错误。

于 2013-05-24T20:19:38.893 回答
2

字符串对象在字符串池中创建,在jvm中实现,内部创建和存储字符串对象。创建字符串的最佳方法是String s ="hello";

String s= new String ("hello");

创建 2 个不必要的 String 对象。

于 2013-05-24T20:09:01.353 回答
1

像“hello”这样的字符串字面量是 Java 中一种罕见的语法糖。它与调用构造函数不同,但它会为您提供对 PermGen 中字符串池中相等字符串对象的引用。您的编译器错误是因为 String 类具有重载的构造函数,并且当您传递 null 时,编译器无法判断您正在调用哪一个。

于 2013-05-24T20:09:54.557 回答
1

Java 编译器对字符串进行了一些优化,以防止多个 String 对象具有相同的值。它被称为“字符串实习”。这就是为什么 Java 中的 String 是不可变的。在第一种情况下,您实际所做的是将现有 String 对象的引用分配给新变量。您可以将其想象为您实例化了任何其他类并将其分配给另一个变量:

WhateverClass object1 = new WhateverClass();
WhateverClass object2 = object1; // No new instance created, just assigning a reference
boolean areEquals = object1 == object2; // This is true, same reference
String string1 = "foo";
String string2 = "foo";
String string3 = new String("foo");
areEquals = string1 == string2; // true, same reference
areEquals = string1 == string3; // false, different objects

但是,使用“新”您会强制创建一个新实例(占用更多内存,速度较慢......),因此您应该尽可能避免这种情况。String 构造函数中带有 null 参数的编译错误是完全不同的故事

于 2013-05-24T20:19:44.090 回答
0

String 和其他扩展 Number 的类(如 Integer)使用池来存储一些对象,因此当您请求它们时,它们已经创建。在 String 类中,所有文字字符串和字符串值常量表达式都是 interned ,这称为String interning。因此,当您使用“”创建字符串时,所有这些字符串都会被保留(如果不存在则创建或如果存在则检索)。类似于flyweight pattern.

 String s = new String(null) // doesnt compile cause it's ambiguous
 String s = new String((String)null) // u can try this, but u will have a RuntimeException(NullPointerException) if u use this variable for something

所以如果你想测试

String s = new String("hello");  // "hello" is interned cause it's a literal and with the new clause u waste memory, cause u create max 2 times, one in the heap  and the other in permgen"
String s2 = "hello";
String s3 = "hello";
   System.out.println(s==s2); // false
   System.out.println(s2 == s3); // true
   System.out.println(s.equals(s2));//true
于 2013-05-24T21:54:25.910 回答
-1

在 Java 中,对象是用它们的引用实例化的。如果您创建一个字符串“Hello”,则会在堆栈中创建一个指向字符串的引用(指针)。所以如果你写: String s = null 引用将被实例化,但没有任何指向字符串的指针。如果你写 new String(null) 它必须创建一个指向空内存区域的指针,这就是你得到编译错误的原因。希望有所帮助,西莫

于 2013-05-24T20:13:14.347 回答