• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Bear Bibeault
  • Junilu Lacar
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Henry Wong
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • salvin francis
  • Frits Walraven
Bartenders:
  • Scott Selikoff
  • Piet Souris
  • Carey Brown

Conversion questions from Dan's exams.

 
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The following are 2 questions that are somewhat similar, yet yield different results.
Question 1:
class A {}
class B {
static void m(Object x) {System.out.print("Object");}
static void m(String x) {System.out.print("String");}
public static void main(String[] args) {
m(null);
}
}

What is the result of attempting to compile and run the above program?
a. Prints: Object
b. Prints: String
c. Compiler error.
d. Runtime error.
e. None of the Above
Answer: b.
Explanation:
Section 15.12.2.2 of the Java Language Specification states the following. If more than one method declaration is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen. The informal intuition is that one method declaration is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error. End of quote. In this case, the String type is more specific than the Object type.
Question 2:
class A {}
class B {
static void m(Object x) {System.out.print("Object");}
static void m(String x) {System.out.print("String");}
static void m(A x) {System.out.print("A");}
public static void main(String[] args) {
m(null);
}
}

What is the result of attempting to compile and run the above program?
a. Prints: Object
b. Prints: String
c. Compiler error.
d. Runtime error.
e. None of the Above
Answer: c
In question 2, why doesn't it pick A? A being a user-defined class should be considered more specific than String or Object, right?
Can someone explain to me how the compiler decides what is more specific than the other?
Thanks
Sharda
 
Ranch Hand
Posts: 154
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hey, you recently posted a similar question. Check out the first link - that is your post. I had given a detailed explanation - just scroll down. If you haven't understood, thats it, I am registering myself for an effective communications class.
https://coderanch.com/t/239328/java-programmer-SCJP/certification/null-argument-method-being-passed
https://coderanch.com/t/369853/java/java/Method-overloading-derived-class
I think a topic in the newsletter should be dedicated exclusively to this subject. Seen a lot of questions lately. And the output varies with the JDK version too.
 
Ranch Hand
Posts: 279
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry Vin, I haven't read your reply, but I would simply put it this way.
In case of String and Object, String is more specific as String is subclass of Object and the paramater (null) that can be assigned to Object can be assigned to String as well which is a subclass of Object. So generally speaking String is more specific in this case because it's a subclass, this is how I understood it from Dan's explanation...
in case of String and A, they are both peer classes, String is subclass of Object and A is subclass of Object, String is-not-a A and A is-not-a String. So as they are both peers, non of them is more specific than the other, if hypothetically A is a subclass of String - can't happen though - then A would be more specific than String..
C extends B, B extends A
then C is more specific than B and B is more specific than A, that's if the parameter passed is of type C and B respectivily.
HTH
 
Sharda Vajjhala
Ranch Hand
Posts: 57
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Vin,
Thanks for your explanations. In the 1st link, Case 4:


If you have methods as follows,
void someMethod( Base obj ); // 1
void someMethod( Level1_A obj ); // 2
void someMethod( Level1_B obj ); // 3
void someMethod( Level2_A obj ); // 4
and you invoke someMethod() with argument null, then you STILL have ambiguity because now the confusion is between invoking the Level1 method or the Level2 method i.e., between 3 & 4.


Since anything passed to Level2_A can be passed to Level1_A, Level2_A is more specific than Level1_A. The Level1_A and Level1_B are at the siblings and hence are considered "equal". Since Level2_A is more specific than Level1_A, Level2_A should be more specific than Level1_A too.
Where is the ambiguity in this case?
All the other cases are very clear to me.
Thanks
Sharda
 
Alfred Kemety
Ranch Hand
Posts: 279
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Well let me then explain how the compiler think of it in a different way...
Case of invokation at //1
1- refA is of reference type A1, it can be assigned to A1, A and X.
2- So the methods at 1` and 12 can be invoked. Now we have to choose between the 2, right?
3- compiler see the reference types of parameters of the methods at 1` and 12. X - the reference type needed for method at 12 - can NOT be casted to A - the reference type needed for method at 1`- BUT A can be cast to X. And for these 2 bold statments A - method at 1` - is more specific than X - method at 12 -.
Same logic goes to case of invokation at 2.
Case of invocation at 3 is only possible by using the method declared at 12, so no problem
at 4 - that is actually commented - null can be assigned to A, B, X and thus the 3 methods can be used. of course A is more specific than X and B is more specific than X for the same reason stated above. So method at 12 is out of the game. Left is A - 1` - and B - 2` -
A can't be casted to B, and B can't be casted to A, they are peers.. so the compiler can't say which method is more specific than the other.. and from here comes the Ambiguity.
Hope that was clear
 
Ranch Hand
Posts: 1865
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Sharda Vajjhala:
In question 2, why doesn't it pick A? A being a user-defined class should be considered more specific than String or Object, right?
Thanks
Sharda


Your assumption is logical, but the process implemented by the compiler is far more simplistic. If ambiguous class hierarchies exist then the compiler isn't going to make a judgment call as to which hierarchy is more specific. Instead, the compiler will just throw an exception. In other words, the compiler is happy to make a judgment call within a single hierarchy, but it won't select one hierarchy over another.
 
Dan Chisholm
Ranch Hand
Posts: 1865
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here's an example that demonstrates that the compiler is not able to recognize the more specific method even when it is obvious to a person.
 
Ranch Hand
Posts: 86
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sorry to ask a stupid question... is null a subclass of another class, say Object?
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A is a subclass of Object, thus is more specific than Object but ambigous regarding String.
__________________________________________

I think the example given by Dan shows a bug in the compiler.
__________________________________

There is a null type but it is not accessible for the programmer. That is, whenever you encounter null in a program is a special value than can be assigned, as a widdening conversion, to any variable of a reference type. Never it will appear in the place of a type like "null myNull;" or something like... "(null) variable;"
 
Dan Chisholm
Ranch Hand
Posts: 1865
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Jose Botella:
I think the example given by Dan shows a bug in the compiler.


I thought it was a feature, but I'm open to the possibility that it's a bug. Is there a particular JLS reference that comes to mind?
 
Ranch Hand
Posts: 223
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Jose Botella:

I think the example given by Dan shows a bug in the compiler.


I can't follow how did you deduce that there's a bug with the compiler.
After the method's resolution process, the compiler wind up with the following methods:

The compiler can't resolve which one is more specific and this is true since you can't cast a Cat to BlackLabradorRetrieverPuppyThatIsSmallerThanOthers which is a Dog or BlackLabradorRetrieverPuppyThatIsSmallerThanOthers to a Cat.
 
Vin Kris
Ranch Hand
Posts: 154
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Agree with Shishio. This case too can be explained by the definition of most specific method.
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes you are right. This explained it for me. Thanks


The compiler can't resolve which one is more specific and this is true since you can't cast a Cat to BlackLabradorRetrieverPuppyThatIsSmallerThanOthers which is a Dog or BlackLabradorRetrieverPuppyThatIsSmallerThanOthers to a Cat.

    Bookmark Topic Watch Topic
  • New Topic