aspose file tools*
The moose likes Beginning Java and the fly likes Another Simple Query Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Another Simple Query" Watch "Another Simple Query" New topic
Author

Another Simple Query

Varun Khanna
Ranch Hand

Joined: May 30, 2002
Posts: 1400
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());
}
}


- Varun
Sean MacLean
author
Ranch Hand

Joined: Nov 07, 2000
Posts: 621
This questions seems better suited to Java In General (Beginner) so I'm moving it there.
Sean
Bosun Bello
Ranch Hand

Joined: Nov 06, 2000
Posts: 1510
What do you mean by so unexpected? You are adding null to a string. I think you need a good Java textbook.


Bosun (SCJP, SCWCD)
So much trouble in the world -- Bob Marley
frank davis
Ranch Hand

Joined: Feb 12, 2001
Posts: 1479
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

Joined: Feb 26, 2001
Posts: 5018
    
    8

"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

Joined: Feb 26, 2001
Posts: 5018
    
    8

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

Joined: Jul 11, 2001
Posts: 14112
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"


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 5018
    
    8

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

Joined: Mar 25, 2001
Posts: 1752
    
    2
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

Joined: Mar 25, 2001
Posts: 1752
    
    2
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

Joined: Feb 26, 2001
Posts: 5018
    
    8

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

Joined: Mar 25, 2001
Posts: 1752
    
    2
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

Joined: Feb 26, 2001
Posts: 5018
    
    8

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
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Another Simple Query