jQuery in Action, 3rd edition
The moose likes Beginning Java and the fly likes perplexing program Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "perplexing program" Watch "perplexing program" New topic

perplexing program

Jim A Anderson

Joined: Mar 16, 2004
Posts: 5
The following pgm prints "String Version", but why??? How does the compiler and/or runtime environment decide to use the method that prints "String Version"?
public class AQuestion
public void method(Object o)
System.out.println("Object Version");
public void method(String s)
System.out.println("String Version");
public static void main(String args[])
AQuestion question = new AQuestion();

Nathaniel Stoddard
Ranch Hand

Joined: May 29, 2003
Posts: 1258
Here's my problem with the last response:
And by the way --- I really have no idea why it does this.
BUT, which method the JVM invokes is not done polymorphically! It is all determined at compile time.
If I have public void fn(String), public void fn(Object), and I invoke with fn((Object) new String), it will invoke the Object-overloaded method! So, since this is true, the JVM will have to have some explicit means of choosing which method to invoke when I pass fn(null)! But which one? It's supposed to be decided at compile time, and that can't be done since it's an ambiguous call.
I thought maybe it chooses the most-specialized class type and calls that method. String is derived from Object, so it choose that one (why? I don't know). I'd be interested to find out which one it would choose if you gave it a choose between two methods whose argument type were the same level of descendent from Object. (String and Integer) -- pass in null and let us know what happens.

Nathaniel Stoddard
Ranch Hand

Joined: May 29, 2003
Posts: 1258
Amazingly, my previous post was almost correct.
Java will try and determine the most specific method to pass null to if it is ambiguous. Since String is more specific than Object, it will pass null to the String method.
My inquiry regarding two equally specific arguments to separate methods would result in a compile-time error since neither is most-specific, and according to the language specs there truly is an ambiguity.
What a puzzler.
In case you're wondering where in the specs, try here and a little farther down in section
[ March 16, 2004: Message edited by: Nathaniel Stoddard ]
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
It's kinda odd looking but you can cast null:
method( (Long)null );
Some times you have to do this to call exactly the method you had in mind. Like if one method takes a String and another takes a Long you might have to cast null to be sure which one you get.

A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
John Smith
Ranch Hand

Joined: Oct 08, 2001
Posts: 2937
What's at play here is the difference between the overrided and overloaded methods. There is no polymorphism when you use overloading, -- the selection between the overloaded methods is static and is made at a compile time. For the overriddend methods, the selection is dynamic and is made at a run time.
The reason that the method(String s) is invoked in the code example above is because the most specific overloaded method always gets executed. Here is an interesting experiment that you can do. Add one more method to the class above:

Guess what happens? The code will not even compile, because Integer is as "specific" as String, and compiler simply can't make a choice between the two methods.
P.S. I just noticed that Nathaniel solved this puzzle before I posted. Congrats!
[ March 16, 2004: Message edited by: Eugene Kononov ]
I agree. Here's the link: http://aspose.com/file-tools
subject: perplexing program
It's not a secret anymore!