为什么使用空值初始化String (String)构造函数会导致编译时错误?我认为有两个以上的构造函数接受Object类型参数,当以null值初始化时,它不知道从哪里开始。我想知道是否还有其他原因。
String s = new String(null); // compile time error
StringBuffer sb = new StringBuffer(null); // no error
通常情况下,当调用一个可能有多个重载版本的构造函数或方法时,Java会选择最具体的构造函数或方法。第15.12.2节的Java语言规范详细解释了这一点。
假设你有两个重载的方法,像这样:
public void method(Object o) {
// ...
}
public void method(String s) {
// ...
}
当您调用method(null)
时,这两种方法都适用。Java会选择最具体的方法,即在本例中接受String
参数的第二个方法,因为String
是比Object
更具体的类型。String
类的构造函数:String(byte[] bytes)
String(char[] value)
String(String original)
String(StringBuffer buffer)
String(StringBuilder builder)
请注意,byte[]
、char[]
、String
、StringBuffer
和 StringBuilder
这些类型之间没有层次关系,因此无法说其中一个构造函数比其他构造函数更具体。所以,Java编译器不知道选择哪个构造函数,会给出错误提示。
byte[] b = null;
String s = new String(b); // complier should be fine with this
char[] c = null;
String s = new String(c); // complier should be fine with this
.... // you can try other constructors using similar approach.
public class Test {
public Test(Object obj) {
System.out.println("Object");
}
public Test(String obj) {
System.out.println("String");
}
public static void main(String[] args) {
new Test(null);
}
}
如果可用相同类型的构造函数,则编译器将选择最具体的构造函数,因此不会引发任何编译时错误。但是,如果我更改类为:
public class Test {
public Test(Long lg){
System.out.println("Long");
}
public Test(Object obj) {
System.out.println("Object");
}
public Test(String obj) {
System.out.println("String");
}
public static void main(String[] args) {
new Test(null);
}
}
这将会引发编译时错误。因为涉及到两个不同的构造函数层次结构,编译器无法做出决策。一个层次结构是:Object-->String,另一个是Object-->Long,所以没有办法选择Long或String类型的构造函数。
String有许多构造函数。它们都可以使用null。
编辑:在Java 6中,String有5个一参数构造函数。感谢BoltClock和Adeel Ansari!
StringBuffer
应该会出现NullPointerException
(当然,这并不是重点)。 - BoltClock