This week's book giveaway is in the Java in General forum.
We're giving away four copies of Think Java: How to Think Like a Computer Scientist and have Allen B. Downey & Chris Mayfield on-line!
See this thread for details.
Win a copy of Think Java: How to Think Like a Computer Scientist this week in the Java in General forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Another Simple Query

 
Varun Khanna
Ranch Hand
Posts: 1400
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi another query....why is the output of the following code so unexpected ??
public class Test{
public static void main(String arsg[]){
String s = null;
String s1= "null";
String s3 = s+s1;
System.out.println(s3.length());
}
}
 
Sean MacLean
author
Ranch Hand
Posts: 621
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This questions seems better suited to Java In General (Beginner) so I'm moving it there.
Sean
 
Bosun Bello
Ranch Hand
Posts: 1511
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What do you mean by so unexpected? You are adding null to a string. I think you need a good Java textbook.
 
frank davis
Ranch Hand
Posts: 1479
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I can see how that would be seen as sort of weird, since people often think of a null value is no value or the absence of a value not the literal value "null". Yet String will hold the value of null and the literal "null" will print out even if nothing is explicitly ever assigned to the String :
public class nully{

String s ;
public static void main(String arsg[]){
nully nuly = new nully();

String s1= "null";
String s3 = nuly.s+s1;
System.out.println(s3.length());
System.out.println(s3);
}
}
Prints 8 and "nukllnull".
If you're doing String concatenation with a String you think is empty that would be an unexpected result to some people I'm sure.
[ May 30, 2002: Message edited by: herb slocomb ]
 
Junilu Lacar
Bartender
Posts: 7466
50
Android Eclipse IDE IntelliJ IDE Java Linux Mac Scala Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
"varun"
Again, please change your display name to conform to the Naming Policy. Thanks.
You will get what you expect with the following code:
String s = "";
String s1= "null";
String s3 = s+s1;
System.out.println(s3.length()); // 4
Behind the scenes, the static method String.valueOf(Object) eventually gets invoked and this method returns the literal "null" for null references (which is what s is). The following code will have the same results as your code snippet:
Object aNullRef = null;
String s1= "null";
String s3 = aNullRef + s1;
System.out.println(s3.length());

HTH,
Junilu
 
Junilu Lacar
Bartender
Posts: 7466
50
Android Eclipse IDE IntelliJ IDE Java Linux Mac Scala Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
interestingly enough the following code results in a runtime error:
Object o = String.valueOf(null);
java.lang.NullPointerException
at java.lang.String.<init>(String.java:219)
at java.lang.String.valueOf(String.java:1961)
at Q1.q2(Q1.java:18)
at Q1.main(Q1.java:8)
Exception in thread "main"
Whereas this is OK,
String s = null;
Object o = String.valueOf(s);
I wonder if this is a bug... (using jdk version "1.3.1_02")
Junilu
[ May 30, 2002: Message edited by: Junilu Lacar ]
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The reason is that
s1 + s2
gets translated by the compiler to something like
new StringBuffer().append(String.valueOf(s1)).append(String.valueOf(s2)).toString();
and the result of String.valueOf(null) is in fact "null"
 
Junilu Lacar
Bartender
Posts: 7466
50
Android Eclipse IDE IntelliJ IDE Java Linux Mac Scala Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The reason is that
String.valueOf(null) is in fact "null"

You were probably replying to the original question but like I said, the expression String.valueOf() will result in a runtime exception when passed the literal null value (at least in the version of the JDK that I'm using). Can't think of any reason for that behavior other than that it's a bug in the Java compiler or runtime.
Junilu
 
Michael Matola
whippersnapper
Ranch Hand
Posts: 1819
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Junilu Lacar:
interestingly enough the following code results in a runtime error:
Object o = String.valueOf(null);
java.lang.NullPointerException
at java.lang.String.<init>(String.java:219)
at java.lang.String.valueOf(String.java:1961)

Look at line 1961 of String. This is the version of valueOf() that's getting invoked:

not String.valueOf( Object object )
 
Michael Matola
whippersnapper
Ranch Hand
Posts: 1819
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Probably has to do with which version of an overloaded method is considered the most specific when the parameter is the null literal. (I'm pretty fuzzy on all that most specific method business.)
Junilu's "s" is a String reference type (whose value just happens to be null) and therefore the String.valueOf( Object object ) is the version of valueOf that gets invoked.
Isn't the null literal considered some special referenece type? (You can't declare a variable to be type null, right?)
[ May 30, 2002: Message edited by: Michael Matola ]
 
Junilu Lacar
Bartender
Posts: 7466
50
Android Eclipse IDE IntelliJ IDE Java Linux Mac Scala Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're right, Michael. I didn't notice the char[] version. Now I'm wondering why java's not giving an "ambiguous" error since a char[] is still an Object, why would it be a more specific match over Object for the null literal? Hmmm... where's Val "the walking JLS" when you need him...
 
Michael Matola
whippersnapper
Ranch Hand
Posts: 1819
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Interesting.
If you run the following code,

You get the expected output
Object version getting called.
Object version getting called.
If you add another callMe method, say

You see that the array of ints version is getting called if you pass the null literal.
Now if you try to add a third callMe

The code won't compile because of the ambiguous method call.
JuniluNull.java:24: reference to callMe is ambiguous, both method callMe(int[]) in JuniluNull and method callMe(java.lang.Object[]) in JuniluNull match callMe( null ) ;
Note, this seems to work for any subclasses of Object, not just arrays. In other words, the null literal passed as a parameter seems to match a method that takes Object, unless there's also a version that takes some subclass of Object, in which case it matches that version. If there are multiple versions for different subclasses of Object, then the compiler shrieks.
 
Junilu Lacar
Bartender
Posts: 7466
50
Android Eclipse IDE IntelliJ IDE Java Linux Mac Scala Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
since a char[] is still an Object, why would it be a more specific match over Object for the null literal?
OK, looked it up in the JLS 15.12.2.2 and it says if T can be converted to U by method invocation conversion then the method version with type T is more specific.
So if you have
methodX(T[] t) {} // where T can be any type, reference or primitive
methodX(Object u) {}
it seems that invoking methodX(null) will always match the T[] version.
Junilu
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic