I see that you already are a ranch hand. It would seem that you would have adjusted your display name to meet the JavaRanch Naming Policy by now. Please do so as soon as possible. You can change it here. It would be a shame to have to close your account now.
JavaBeginnersFaq "Yesterday is history, tomorrow is a mystery, and today is a gift; that's why they call it the present." Eleanor Roosevelt
Marilyn de Queiroz
Joined: Jul 22, 2000
String is a rare class in Java. It's allowed to straddle the line between behaving as an object (using new() ) and behaving as a primitive )using direct assignment. The designers knew String objects would be prominent in almost any program. To conserve the run-time cost of creating them, they chose to allow static String assignments. Static assignments are "paid for" at compilation time, where they can be less of a burden. When you allocate space for a String using new, that object goes to the heap and is garbage-collectible once it's fully dereferenced. A static String remains in program memory no matter what. Even if you completely dereference it, it's there and will get used again if you re-assign its value.
-- Michael Ernest, co-author of: The Complete Java 2 Certification Study Guide
A new String is already null. Trying to create a second null String is confusing the compiler. StringBuffer, on the other hand, is "just" another object.
If you want to assign null to a String reference, try String s = null; [ February 05, 2005: Message edited by: Marilyn de Queiroz ]
The word "ambiguous" means "could mean more than one thing." The compiler doesn't know which thing you mean, so it just reports an error. String has four constructors (in JDK 1.4, anyway) that you might mean: one that takes a byte, one that takes a char, one for String, and one for StringBuffer. "null" might mean any of these, so the compiler doesn't know what you want.
In contrast, StringBuffer has only one constructor that accepts an argument that could be null: one that takes a String.
If you write, for example,
String s = new String((char) null);
this will compile, as you're telling the compiler what you mean. Of course, then you'll get an error at runtime!
Soumy's display name has changed several times now. Soumy, please use a display name with a complete last name, not an abbreviation. I believe you were using one in the past, but I don't remember what it was. Thanks.
[MdQ]: A new String is already null.
I can't imagine what is meant by this statement. Perhaps you're saying the reference would be null? Not the object itself, surely? Of course the reference is only null if you don't initialize it to something else...
Michael Ernest's quote seems to be about string literals, though he calls them static strings for some reason. I can't see how it has anything to do with the question at hand. The reason that the compiler considers new String(null) to be ambiguous is because String has multiple constructors which take a single reference type as an argument:
public String(byte arr) public String(char arr) public String(String s) public String(StringBuffer sb) public String(StringBuilder sb) (JDK 1.5)
When you say new String(null), the compiler has no way of knowing which of these is intended, since null could be any of those four or five types. You could fix this by telling the compiler which one to use, with a cast. E.g.:
new String((char) null)
In contrast, StringBuffer has only two constructors which take a single reference type:
Why does the compiler not consider new StringBuffer(null) to be ambiguous, given that there is more than one constructor that seems applicable here? The reason for this is somewhat subtle - it's because String is a subtype of CharSequence, and the JLS requires that the compiler choose the most specific interpretation of the type of null, from all possible interpretations. String is a more specific subtype of CharSequence, so the compiler assumes that null is of type String, and proceeds accordingly. Looking back at the String constructor - none of the argument types is more specific than all the others. In fact none are more specific than any of the others - none is a subtype of one of the other argument types. String is not a subtype of byte; byte is not a subtype of char, etc.
Now, why anyone would want to do anything like this - passing a null to a String or StringBuffer constructor - is another question. Passing null into one of these constructors would cause a NullPointerException at runtime. There's no possible benefit to doing something like this. So...
[MdQ]: If you want to assign null to a String reference, try String s = null;