Java Forum / General / October 2005
difference between null object and null string
gokul.b@gmail.com - 10 Oct 2005 20:14 GMT please look at the code snippet below:-
public class PowerSupply {
public PowerSupply(Object voltage){ System.out.println ("PowerSupply(Object) executed"); } public PowerSupply(String voltage){ System.out.println ("PowerSupply(String) executed"); } public PowerSupply(){ System.out.println ("No argument constructor execute"); } public static void main(String[] args) { PowerSupply ps = new PowerSupply(null); } }
which is the constructor invoked?
The answer is the String constructor is invoked. I do not understand why the Object constructor wasnt invoked. in the case of" ps = new PowerSupply((Object)null)", the Object constructor is invoked.
Any insight into the java' interpretation of null is greatly appreciated! thx g
Roedy Green - 10 Oct 2005 21:17 GMT >The answer is the String constructor is invoked. I do not understand >why the Object constructor wasnt invoked. >in the case of" ps = new PowerSupply((Object)null)", the Object >constructor is invoked. Print out what was passed. The mystery might become clear. null does not have a type so (Object) null is meaningless
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Eric Sosman - 10 Oct 2005 21:38 GMT Roedy Green wrote On 10/10/05 16:17,:
>>The answer is the String constructor is invoked. I do not understand >>why the Object constructor wasnt invoked. [quoted text clipped - 3 lines] > Print out what was passed. The mystery might become clear. null does > not have a type so (Object) null is meaningless `(Object)null' is meaningFUL, since using it changes the behavior of the program. I'm not enough of a language lawyer to say whether `null' has "no type" or "all types" or "an inifintely flexible pseudo-typish sort of wossname, seewatimean?" However, the expression `(Object)null' most certainly has a type, namely, "reference to Object."
 Signature Eric.Sosman@sun.com
Stefan Ram - 10 Oct 2005 21:52 GMT >the behavior of the program. I'm not enough of a language >lawyer to say whether `null' has "no type" or "all types" The type of the null literal is "null". JLS3, 3.10.7.
John C. Bollinger - 11 Oct 2005 03:23 GMT >>the behavior of the program. I'm not enough of a language >>lawyer to say whether `null' has "no type" or "all types" > > The type of the null literal is "null". JLS3, 3.10.7. That's not quite what the referenced material says, but it is true that formally speaking the null literal has a type, the null type. Per JLS3, 4.1:
"There is also a special null type, the type of the expression null, which has no name. Because the null type has no name, it is impossible to declare a variable of the null type or to cast to the null type. The null reference is the only possible value of an expression of null type. The null reference can always be cast to any reference type. In practice, the programmer can ignore the null type and just pretend that null is merely a special literal that can be of any reference type."
Note: when the text says "the null type has no name" it is referring to a name recognized by Java; it certainly does have a name by which the JLS refers to it ("the null type").
Every rvalue expression in Java, including the null literal, has one and only one type.
 Signature John Bollinger jobollin@indiana.edu
gokul.b@gmail.com - 10 Oct 2005 21:47 GMT After I enabled printing of the input,if I pass a null, the output is displayed as "null".
Interestingly, if I modify the constructor that takes an Object to a constructor that takes an Integer, I get a compilation error (ambigous definition of constructor).
I was expecting the ambigous definition of constructor in the very first place. Dont know why java simpley "ignores" a constructor that takes an Object
Eric Sosman - 10 Oct 2005 22:27 GMT gokul.b@gmail.com wrote On 10/10/05 16:47,:
> After I enabled printing of the input,if I pass a null, the output is > displayed as "null". [quoted text clipped - 6 lines] > first place. Dont know why java simpley "ignores" a constructor that > takes an Object Java does not "ignore" the (Object) constructor. Java has a whole lot of rules to determine how overloaded methods and constructors are resolved. They're spelled out in great detail in the Java Language Specification, but the informal notion is that Java uses the "most specific" overloading that it can. Consider these three methods with the same name:
void method(Object o) { System.out.println(1); } void method(Number n) { System.out.println(2); } void method(Integer i) { System.out.println(3); }
When you write `method(new HashMap())' which method is called? Well, a HashMap is not an Integer and not a Number, but it is an Object and so method #1 is called; it's the only possible candidate.
Things get more interesting when more than one candidate might be applicable, as in `method(new Integer(42))'. All three methods could conceivably apply, since an Integer is an Integer (duh...), but is also a Number and also an Object. Java resolves this in favor of method #3, because Integer is the "most specific" description for an Integer reference.
Finally, consider `method(new Double(42.0))'. A Double is not an Integer so method #3 isn't called, but a Double is a Number and is an Object. Number is "more specific" than Object, so method #2 is called.
Now to your case. You wrote `method(null)' (in essence) and since `null' itself carries no type information it's not immediately clear what should happen. Java considers Object, Number, and Integer, and finds that all three of them could match `null'. However, Integer is still the "most specific," so method #3 is used. You could get different results (which ones?) by writing `method((Long)null)' or `method((URL)null)'.
But then you changed things by adding yet another method:
void method(String s) { System.out.println(4); }
This muddies the waters. The calls with HashMap, Integer, and Double and with `null' cast to a type work just as before, but what about the call with plain `null' as an argument? All four methods might apply, but now Java can't decide what to do because String and Integer are "equally specific." javac throws up its hands and tells you to stop speaking in riddles.
Things get more complex when there are multiple arguments, when you've got classes that implement several interfaces, and so on. The exact rules are in the JLS, but mostly they just try to formalize this notion of "more specific."
 Signature Eric.Sosman@sun.com
zero - 10 Oct 2005 23:00 GMT Eric Sosman <eric.sosman@sun.com> wrote in news:diembq$9sv$1 @news1brm.Central.Sun.COM:
> gokul.b@gmail.com wrote On 10/10/05 16:47,: >> After I enabled printing of the input,if I pass a null, the output is [quoted text clipped - 18 lines] > void method(Number n) { System.out.println(2); } > void method(Integer i) { System.out.println(3); } <snipped>
Excellent explanation :-) One question though: what happens when you use method call method(1) - ie with an int. Does it, as I would expect, get converted to Integer, calling the third method?
Hendrik Maryns - 11 Oct 2005 10:52 GMT zero schreef:
> Eric Sosman <eric.sosman@sun.com> wrote in news:diembq$9sv$1 > @news1brm.Central.Sun.COM: [quoted text clipped - 28 lines] > method call method(1) - ie with an int. Does it, as I would expect, get > converted to Integer, calling the third method? Only if you use 5.0, which does autoboxing. In 1.4, you'd get an error.
 Signature Hendrik Maryns
================== www.lieverleven.be http://aouw.org
Ross Bamford - 10 Oct 2005 23:13 GMT >> The answer is the String constructor is invoked. I do not understand >> why the Object constructor wasnt invoked. [quoted text clipped - 3 lines] > Print out what was passed. The mystery might become clear. null does > not have a type so (Object) null is meaningless Actually I think the compiler uses it as a hint as to which method descriptor to generate the call to. If, in the source, you just have 'null' , evidently it creates an INVOKESPECIAL <init>(Ljava/lang/String;)V. If, however, in your source you specify (Object)null, then the generated instruction points instead to <init>(Ljava/lang/Object;)V .
It's true that null has no type in the JVM, but obviously it helps the compiler decide which (non-virtual) constructor to dispatch to.
I'm not sure what the order of preference is if unspecified, though I imagine it's defined in the spec.
 Signature Ross Bamford (rosco@roscopeco.remove.co.uk)
John C. Bollinger - 11 Oct 2005 03:32 GMT >>> The answer is the String constructor is invoked. I do not understand >>> why the Object constructor wasnt invoked. [quoted text clipped - 10 lines] > specify (Object)null, then the generated instruction points instead to > <init>(Ljava/lang/Object;)V . It's more than a hint. "(Object) null" is a typecast expression whose /type/ is Object and whose /value/ is null. The compiler uses the type of the expression to select the appropriate method.
> It's true that null has no type in the JVM No, it isn't. See other posts in this thread, or read JLS3 section 4.1.
>, but obviously it helps the > compiler decide which (non-virtual) constructor to dispatch to. > > I'm not sure what the order of preference is if unspecified, though I > imagine it's defined in the spec. Naturally; See JLS3 section 15.12. Be warned: this is a lengthy and complicated section of the spec. For the less intrepid, Eric Sosman gave a good run-down of how all that applies to this particular case.
 Signature John Bollinger jobollin@indiana.edu
Mike Schilling - 12 Oct 2005 00:18 GMT > Naturally; See JLS3 section 15.12. Be warned: this is a lengthy and > complicated section of the spec. For the less intrepid, Eric Sosman gave > a good run-down of how all that applies to this particular case. If you can find JLS2, read the corresponding section there instead. It answers the question about null as an argument without haveing to discuss variable-length parameter lists, generics, etc. Still complex, but not brain-damaging the way JLS3 is.
Roedy Green - 11 Oct 2005 06:31 GMT >It's true that null has no type in the JVM, but obviously it helps the >compiler decide which (non-virtual) constructor to dispatch to. It seems to me that (Integer)null might either be a compile time error or invalid cast exception at run time. From the discussions, I gather neither happens.
I guess what Eric's findings mean is :
Integer n = null; someMethod ( n );
has the same effect as
someMethod ( (Integer) null );
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
Ross Bamford - 11 Oct 2005 13:12 GMT >> It's true that null has no type in the JVM, but obviously it helps the >> compiler decide which (non-virtual) constructor to dispatch to.
> It seems to me that (Integer)null might either be a compile time error > or invalid cast exception at run time. From the discussions, I gather > neither happens.
> I guess what Eric's findings mean is :
> Integer n = null; > someMethod ( n );
> has the same effect as
> someMethod ( (Integer) null ); Internally, CHECKCAST doesn't throw on null, and it does also influence the runtime type of the reference. For example, if you have an Object on top of the stack and want to return if from a String method, you have to first do a checkcast on it. So yes, since a cast of null never actually makes it into bytecode, and is just used by the compiler to decide which overload to dispatch to before being discarded, they are equivalent. The compiler uses the dynamic type of 'this', and the static types of the arguments to select an overload to call. So in this case, although the null cast is really nonsense, the compiler takes it as a hint about which method descriptor to go for.
I just did a quick experiment, and this is borne out. Assuming the existence of a String and Object overload, the statments:
aMethod(null); aMethod((Object)null);
Object aNull = null; aMethod(aNull);
come out as:
ALOAD 0 ACONST_NULL // stack now - this .. null INVOKEVIRTUAL aMethod(Ljava/lang/String;)V
ALOAD 0 ACONST_NULL // stack now - this .. null INVOKEVIRTUAL aMethod(Ljava/lang/Object;)V
L1: ALOAD 0 ACONST_NULL ASTORE 1 L2: ALOAD 1 // stack now - this .. null INVOKEVIRTUAL aMethod(Ljava/lang/Object;)V
Interestingly, adding a primitive 'int' overload and then casting the null to (Integer), which you would expect to dispatch to the primitive overload in Java 5 (thanks to unboxing) instead dispatches to the Object version. That could be a nasty little gotcha I guess...
 Signature Ross Bamford (rosco@roscopeco.remove.co.uk)
Mike Schilling - 12 Oct 2005 19:43 GMT >>It's true that null has no type in the JVM, but obviously it helps the >>compiler decide which (non-virtual) constructor to dispatch to. > > It seems to me that (Integer)null might either be a compile time error > or invalid cast exception at run time. From the discussions, I gather > neither happens.
> I guess what Eric's findings mean is : > [quoted text clipped - 4 lines] > > someMethod ( (Integer) null ); Yes. I think this is true in general, with any type substitued for Integer and any value substituted for null.
Ross Bamford - 12 Oct 2005 09:54 GMT This is a reply, to a reply by John C. Bollinger, about the message below. Something's gone a bit wrong here, and I've lost the reply itself - sorry!
>>> The answer is the String constructor is invoked. I do not understand >>> why the Object constructor wasnt invoked. [quoted text clipped - 13 lines] > It's true that null has no type in the JVM, > <J.C. Bollinger refers me to JLS> Well, granted, but I'm more of a nuts and bolts man so I try to keep out of the JLS as much as possible (it hurts my head ;)). Thanks for boiling down what it says :) What I was getting at, though, was that in real terms inside the JVM itself, null has no _runtime type_ of it's own, and can be cast to to any other type.
I see so much grossly incorrect and misleading information pass through this newsgroup, that it's good to see the heavyweights still jumping on the only-slightly-relevant detail from the occasional poster.
> but obviously it helps the compiler decide which (non-virtual) > constructor to dispatch to. [quoted text clipped - 3 lines] > > <J.C. Bollinger refers me to JLS> When I said "I imagine it is", I meant say "It is, but I cannot be bothered to find the reference. Go look if you're interested". Thanks for covering my laziness ;)
 Signature Ross Bamford - rosco@roscopeco.remove.co.uk
Hemal Pandya - 11 Oct 2005 09:03 GMT > Any insight into the java' interpretation of null is greatly > appreciated! This was covered here in detail recently. See http://groups.google.com/group/comp.lang.java.programmer/browse_frm/thread/b677d fdb8c1e4133?hl=en&
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|