10

why String (String) constructor with null value cause compile-time error? I think there is 2+ constructor that takes Object and when init. it with null it doesn't know which to start. I'm wonder if there is another reason

String s = new String(null); // compile time error


StringBuffer sb = new StringBuffer(null); // no error
Adeel Ansari
  • 39,541
  • 12
  • 93
  • 133
  • You should get a `NullPointerException` for the `StringBuffer` though when you try to run it (of course, that's beside the point). – BoltClock Jan 26 '11 at 08:20
  • 1
    take a look at http://stackoverflow.com/questions/1545501/which-overload-will-get-selected-for-null-in-java – pingw33n Jan 26 '11 at 08:41

4 Answers4

12

Normally, when you call a constructor or method for which multiple overridden versions might apply, Java will choose the most specific constructor or method. Section 15.12.2 of the Java Language Specification explains this in detail.

Suppose you have two overloaded methods, like this:

public void method(Object o) {
    // ...
}

public void method(String s) {
    // ...
}

When you call method(null), both these methods apply. Java chooses the most specific one, which is in this case the second method, that takes a String - because String is a more specific type than Object.

However, sometimes the most specific constructor or method cannot be determined. If we look at the constructors of class String that take one argument:

String(byte[] bytes)
String(char[] value)
String(String original)
String(StringBuffer buffer)
String(StringBuilder builder)

Note that there is no hierarchy between the types byte[], char[], String, StringBuffer and StringBuilder, so it's not possible to say that one of these constructors is more specific than the others. So, the Java compiler doesn't know which constructor to choose and will give you an error.

Jesper
  • 202,709
  • 46
  • 318
  • 350
11

Because, compiler couldn't figure out which constructor to call. See here that how many one-argument-constructor it has.

[Edited] You said, if there is another reason. So why not try out yourself. Do something like this,

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.
Adeel Ansari
  • 39,541
  • 12
  • 93
  • 133
  • I think so but I'm wonder if there is another reason. I'm now editing my question –  Jan 26 '11 at 08:24
3

Just to add more clarity to the solution:

Take this example:

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);
}

}

It will not throw any compile time error as compiler will choose the most specific constructor of available same types. However, if I change the class to:

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);
}
}

It will throw compile time error. As two separate constructor hierarchies are involved here and compiler has no way to make a decision. One hierarchy is: Object-->String and second is Object-->Long so no way to choose between Long or String type constructors.

Atul S.
  • 31
  • 3
1

String has many constructors. null is available for them.

Edit: String has 5 one-argument-constructor, in Java 6. Thanks BoltClock and Adeel Ansari!

卢声远 Shengyuan Lu
  • 31,208
  • 22
  • 85
  • 130