Win a copy of Mesos in Action this week in the Cloud/Virtualizaton forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

String and StringBuffer::: null

 
Soumy Kumar
Ranch Hand
Posts: 78
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


first line says ambiguous reference as compile error
second line compiles fine

pl explain why??
 
Marilyn de Queiroz
Sheriff
Posts: 9063
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, Soumy S

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.

Thanks!
 
Marilyn de Queiroz
Sheriff
Posts: 9063
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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 ]
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24211
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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!
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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:

public StringBuffer(String s)
public StringBuffer(CharSequence cs)

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;


This, I agree with.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic