Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

perplexing program

 
Jim A Anderson
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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();
question.method(null);
}
}
 
Nathaniel Stoddard
Ranch Hand
Posts: 1258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
Posts: 1258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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 15.12.2.2.
[ March 16, 2004: Message edited by: Nathaniel Stoddard ]
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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.
 
John Smith
Ranch Hand
Posts: 2937
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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 ]
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic