difference between null object and null string

Discussion in 'Java' started by gokul.b@gmail.com, Oct 10, 2005.

  1. Guest

    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
     
    , Oct 10, 2005
    #1
    1. Advertising

  2. Roedy Green Guest

    On 10 Oct 2005 12:14:03 -0700, wrote or quoted :

    >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
    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Again taking new Java programming contracts.
     
    Roedy Green, Oct 10, 2005
    #2
    1. Advertising

  3. Eric Sosman Guest

    Roedy Green wrote On 10/10/05 16:17,:
    > On 10 Oct 2005 12:14:03 -0700, wrote or quoted :
    >
    >
    >>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


    `(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."

    --
     
    Eric Sosman, Oct 10, 2005
    #3
  4. Guest

    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
     
    , Oct 10, 2005
    #4
  5. Stefan Ram Guest

    Eric Sosman <> writes:
    >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.
     
    Stefan Ram, Oct 10, 2005
    #5
  6. Eric Sosman Guest

    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".
    >
    > 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


    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."

    --
     
    Eric Sosman, Oct 10, 2005
    #6
  7. zero Guest

    Eric Sosman <> wrote in news:diembq$9sv$1
    @news1brm.Central.Sun.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".
    >>
    >> 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

    >
    > 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); }
    >


    <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?
     
    zero, Oct 10, 2005
    #7
  8. Ross Bamford Guest

    On Mon, 10 Oct 2005 21:17:35 +0100, Roedy Green
    <> wrote:

    > On 10 Oct 2005 12:14:03 -0700, wrote or quoted :
    >
    >> 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


    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.

    --
    Ross Bamford ()
     
    Ross Bamford, Oct 10, 2005
    #8
  9. Stefan Ram wrote:
    > Eric Sosman <> writes:
    >
    >>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.

    --
    John Bollinger
     
    John C. Bollinger, Oct 11, 2005
    #9
  10. Ross Bamford wrote:
    > On Mon, 10 Oct 2005 21:17:35 +0100, Roedy Green
    > <> wrote:
    >
    >> On 10 Oct 2005 12:14:03 -0700, wrote or quoted :
    >>
    >>> 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

    >
    >
    > 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 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.

    --
    John Bollinger
     
    John C. Bollinger, Oct 11, 2005
    #10
  11. Roedy Green Guest

    On Mon, 10 Oct 2005 23:13:19 +0100, "Ross Bamford"
    <> wrote or quoted :

    >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 );

    --
    Canadian Mind Products, Roedy Green.
    http://mindprod.com Again taking new Java programming contracts.
     
    Roedy Green, Oct 11, 2005
    #11
  12. Hemal Pandya Guest

    Hemal Pandya, Oct 11, 2005
    #12
  13. zero schreef:
    > Eric Sosman <> wrote in news:diembq$9sv$1
    > @news1brm.Central.Sun.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".
    >>>
    >>>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

    >>
    >> 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); }
    >>

    >
    >
    > <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?


    Only if you use 5.0, which does autoboxing. In 1.4, you'd get an error.

    --
    Hendrik Maryns

    ==================
    www.lieverleven.be
    http://aouw.org
     
    Hendrik Maryns, Oct 11, 2005
    #13
  14. Ross Bamford Guest

    On Tue, 11 Oct 2005 06:31:23 +0100, Roedy Green
    <> wrote:


    >> 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...

    --
    Ross Bamford ()
     
    Ross Bamford, Oct 11, 2005
    #14
  15. "John C. Bollinger" <> wrote in message
    news:dif86j$9hk$...
    >
    > 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.
     
    Mike Schilling, Oct 12, 2005
    #15
  16. Ross Bamford Guest

    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!

    On Mon, 10 Oct 2005 23:13:19 +0100, Ross Bamford
    <> wrote:

    > On Mon, 10 Oct 2005 21:17:35 +0100, Roedy Green
    > <> wrote:
    >
    >> On 10 Oct 2005 12:14:03 -0700, wrote or quoted :
    >>
    >>> 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

    >
    > 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,
    > <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.
    >
    > I'm not sure what the order of preference is if unspecified, though I
    > imagine it's defined in the spec.
    >
    > <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 ;)

    --
    Ross Bamford -
     
    Ross Bamford, Oct 12, 2005
    #16
  17. "Roedy Green" <> wrote in
    message news:...
    > On Mon, 10 Oct 2005 23:13:19 +0100, "Ross Bamford"
    > <> wrote or quoted :
    >
    >>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 );


    Yes. I think this is true in general, with any type substitued for Integer
    and any value substituted for null.
     
    Mike Schilling, Oct 12, 2005
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Green
    Replies:
    3
    Views:
    7,943
    Jonathan Allen
    Sep 25, 2004
  2. =?Utf-8?B?QXNoYQ==?=

    the difference between string.Empty and null

    =?Utf-8?B?QXNoYQ==?=, Nov 2, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    16,739
    Kevin Spencer
    Nov 2, 2004
  3. jakk
    Replies:
    4
    Views:
    12,390
  4. narsing
    Replies:
    2
    Views:
    893
    Thomas Weidenfeller
    Oct 23, 2006
  5. tenxian
    Replies:
    7
    Views:
    360
    RedGrittyBrick
    Apr 23, 2008
Loading...

Share This Page