• 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 Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

ID:14 SCJP Question of th day !!!

 
Ranch Hand
Posts: 316
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Tell the output of the following two Programs ???


Reference to Rules !!! SCJP Question of the Day !!!
1)



2)

 
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Cud someone provide an answer to this query? and reason for that behavior?
 
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think neither would compile, as the call

methodOverload(new Dog());

is ambiguous. It uses a Dog reference, that passes all 3 IS-A tests: a Dog IS-A(n) Animal, IS-A Serializable, IS-A MyInterface.
I think the compiler figures out this ambiguity (as it is based on the reference type, not on object type).

I guess (and I will try after writing this post) that, if you give the method an Animal reference to a Dog object, it will compile, and at runtime, the method taking an Animal will be chosen...

Whoa! I like these threads! Congratulations, Sahil, for coming up with this idea!
(unfortunately, for some of them I was not able to respond before trying out the code... so... to be fair I didn't respond at all!)
 
Vicky Mehta
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Valentin.
The compiler seems to contradict and am not able to understand the reason for the same. It would be be nice if anyone can provide an explanation for this question.
@Sahil:
Have you been able to reason out the behavior of the compiler for this question.
Compiler behavior:
1) Compilation Error with ambiguous method.
2) Compilation Successful

My reasoning:
Both MyInterface and java.io.Serializable being Marker interfaces(interfaces with no methods), why is the compiler differentiating between the two interfaces implemented by the class.
 
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
can somebody tell the reason behind this behaviour
 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please apply these 3 lines and debug it.



We got this error because the Animal interface did not implement the MyInterface method. if animal class also implement the MyInterface method , we donot get any problem.

Can anybody verify this?

Regards
Rajan
 
Ranch Hand
Posts: 173
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Vicky Mehta wrote:Thanks Valentin.
The compiler seems to contradict and am not able to understand the reason for the same. It would be be nice if anyone can provide an explanation for this question.
@Sahil:
Have you been able to reason out the behavior of the compiler for this question.
Compiler behavior:
1) Compilation Error with ambiguous method.
2) Compilation Successful

My reasoning:
Both MyInterface and java.io.Serializable being Marker interfaces(interfaces with no methods), why is the compiler differentiating between the two interfaces implemented by the class.



I do not think that compiler treats MyInterface as a marker interface though it has same structural requisites.

But this has definately something to do with using marker interfaces(as defined by Java) as parameter types.

If we use java.lang.Cloneable instead of java.io.Serializable we shall still get the same results.

Trying to find an answer, no luck yet.
 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am very very new to java.

Looks like it is something to do with how the compiler chooses between Matched Arity and Variable Arity methods and JLS 15.12.2.5 Choosing the Most Specific Method.

If the ... is removed from all the method declarations, compilation fails even when the methodOverload(MyInterface a) is commented out.

I am not able to explain why the compiler is able to distinguish 'Animal' as the more specific type when compared to Serializable. If the var-args is removed from methodOverload(MyInterface a), compilation succeeds and that method is executed. This must be because now the Matched Arity method is the most specific.



 
Ranch Hand
Posts: 430
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Nice problem.

It probably has to do with marker interfaces. Runnable also causes compile error.
The problem is that the compiler can't realize that MyInterface is a marker interface. :/

So I think the compiler only realize marker interfaces inside the default API.
 
Ranch Hand
Posts: 37
Netbeans IDE Spring Fedora
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

kris kalapala wrote:
Looks like it is something to do with how the compiler chooses between Matched Arity and Variable Arity methods and JLS 15.12.2.5 Choosing the Most Specific Method.

If the ... is removed from all the method declarations, compilation fails even when the methodOverload(MyInterface a) is commented out.

I am not able to explain why the compiler is able to distinguish 'Animal' as the more specific type when compared to Serializable. If the var-args is removed from methodOverload(MyInterface a), compilation succeeds and that method is executed. This must be because now the Matched Arity method is the most specific.




I too have this doubt about the compiler error - "ambiguous methods", can someone please explain ?
Thanks in advance! I feel, it is like this, in general, overloaded var-args methods are chosen last.
 
Valentin Musoiu
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think I found the solution!!!

Try this:


IT SEEMS ANY ARRAY OBJECT IS SERIALIZABLE!!! (because of the unnamed array superclass or something like that)

The array of Animals (taken in one overloaded method) IS-A Serializable object. Therefore, Animal... a is considered more specific than the var-arg of Serializable, so there is no ambiguity.

@Avishkar: Moreover, the array objects are also Cloneable...

Whoa! This was tough!!!
 
Valentin Musoiu
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello, again.

JLS proof for what I stated in my last post (based on my assumptions):

Every array implements the interfaces Cloneable and java.io.Serializable.



Source: JLS Second Edition, 10.7

Once again, thanks Sahil. These questions are really challenging!!!
 
Valentin Musoiu
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok. I'm not good at explaining, especially when I am very enthusiastic about finding a solution. Therefore, I feel obliged to rephrase what I think is going on in the second snippet of code given by the author of this thread (the one which passes the compilation). You should, consequently, ignore my previous 2 posts



First of all, as I know, a var-arg is treated by the compiler as an array reference. (1)
I think I read this in KS&BB, but I cannot find the exact place now. If this isn't true, then all my demonstration is erroneous.

Second of all, an array is Serializable by default, as we've seen from JLS. (2)

From (1) and (2), we can deduce that a Serializable reference is considered "more specific" than a var-arg. (3)

When there are more overloaded versions of the same methods and the list of references the method is invoked with is compatible with both methods' lists of arguments, the more specific one is chosen. [as stated in JLS 15.12.2.5; Thank you, kris!] (4)

So, applying (3) and (4) to the example, we can say that, if instead of static void methodOverload(java.io.Serializable... a) it would be static void methodOverload(java.io.Serializable a) the method call methodOverload(new Dog()); would still invoke the method that takes Animal... a.

A method taking an argument is preferred over a method taking a var-arg of the same type when we call it using a single argument. [it is, again, more specific] (5)
So, static void methodOverload(java.io.Serializable a) would be preferred over static void methodOverload(java.io.Serializable... a) when calling with a reference of type Serializable.

Therefore, the overloaded version that takes a var-arg of Animal is surely preferred over the overloaded version that takes a var-arg of Serializable, and there is no ambiguity for the compiler in this situation.

Please provide feedback to this post. It would be very helpful.

Thank you!

[ Edited: Wherever I wanted to say "specific" I said the opposite! I am not going to pass SCJP with this continuous recklessness ]
 
Chanakya Gupta
Ranch Hand
Posts: 37
Netbeans IDE Spring Fedora
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Valentin Musoiu wrote:Ok. I'm not good at explaining, especially when I am very enthusiastic about finding a solution. Therefore, I feel obliged to rephrase what I think is going on in the second snippet of code given by the author of this thread (the one which passes the compilation). You should, consequently, ignore my previous 2 posts



First of all, as I know, a var-arg is treated by the compiler as an array reference. (1)
I think I read this in KS&BB, but I cannot find the exact place now. If this isn't true, then all my demonstration is erroneous.

Second of all, an array is Serializable by default, as we've seen from JLS. (2)

From (1) and (2), we can deduce that a Serializable reference is considered "more general" than a var-arg. (3)

When there are more overloaded versions of the same methods and the list of references the method is invoked with is compatible with both methods' lists of arguments, the more general one is chosen. [as stated in JLS 15.12.2.5; Thank you, kris!] (4)

So, applying (3) and (4) to the example, we can say that, if instead of static void methodOverload(java.io.Serializable... a) it would be static void methodOverload(java.io.Serializable a) the method call methodOverload(new Dog()); would still invoke the method that takes Animal... a.

A method taking an argument is preferred over a method taking a var-arg of the same type when we call it using a single argument. [it is, again, more general] (5)
So, static void methodOverload(java.io.Serializable a) would be preferred over static void methodOverload(java.io.Serializable... a) when calling with a reference of type Serializable.

Therefore, the overloaded version that takes a var-arg of Animal is surely preferred over the overloaded version that takes a var-arg of Serializable, and there is no ambiguity for the compiler in this situation.

Please provide feedback to this post. It would be very helpful.

Thank you!


Cool...javascript:emoticon('');Thankyou Valentin Musolu !. JLS 15.12.1, 15.12.2 and 15.12.3 about compile-time method resolving and runtime method invoking are pretty complicated !javascript:emoticon(''); Is there a simple explanation ?
Also,
1. Why does the compiler give the error 'ambiguous methods' ?
2. When can the compiler give this error ?
 
Valentin Musoiu
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey, Chanakaya.

Indeed, the JLS seem very "reader not-at-all-friendly", but that is because it must deal with all possibilities of the Java language, most of which you will never ever encounter (even in SCJP, where there are situations you will never ever encounter in real life programming ). And, secondly, because it uses the arid academic language. However, no matter how much I love Kathy Sierra for her way of putting things, I consider it to be much safer to base my statements on "because James Gosling said so", than on "because Kathy said so"

So, for now I treat JLS as the ultimate answer-provider for situations I think I understood, not to understand something new. There are other books to do that. So, in this matter, I would suggest the SCJP course books. They all deal with the way a method call is verified at compile-time and at runtime.

If I have to sum up what I understood on this matter (although, once again, I am not that good neither at summing up nor at java) you should always remember that the poor compiler doesn't know the actual objects of the program, only the reference types, so he has to do the best he can with that information.
He assumes that the reference types he deals with refer to objects of the same type. So, he checks to see:
-if the method exists, no matter under which form it is called (section 15.12.1)
-the method's accessibility and signature: if it is accessible from that context, and if the argument list is compatible with the parameter list.
-if it finds more, it choses the most specific (based, once again, on the reference types!)
-if there are more "most specific", it signals it (compile-time error)
- (INTERESTING POINT) return types are not taken into account, so, if the chosen method does not return a valid reference (needed in the calling method) it signals the error (it doesn't search another method (less specific)
-then, it even checks if this method will be surely executed, or not. For private methods, static methods or methods called with super. we know for sure they will be executed. For the others, it will be decided at runtime (virtual invocation).(15.12.3)

For the virtual mode invocation, the compiler choses a kind of "worst-case" scenario: nothing can go wrong now: there is a method that can be called. But the method eventually called may not be the one the compiler expects. The objects referenced may be subtypes of the reference types (taken into account by the compiler). So, at runtime, tests are made again, taking into account the new information. So, if the object on which the method is called is a subtype of the reference type, the tests made by the compiler are made again for the object type, then for the parent's type (until the reference type). Don't forget:he argument list is still chosen based on reference types. If nothing is found, the method identified by the compiler is chosen.

I hope I didn't say something wrong. Correct me if I did.


 
Avishkar Nikale
Ranch Hand
Posts: 173
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Valentin,

You the man !!!

Thanks for the research & updates.

I stumbled on other Marker Interfaces which failed & then I realized it has more to do with class hierarchy.

Nice one to know !!!

 
Chanakya Gupta
Ranch Hand
Posts: 37
Netbeans IDE Spring Fedora
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Avishkar Nikale wrote:Valentin,

You the man !!!

Thanks for the research & updates.

I stumbled on other Marker Interfaces which failed & then I realized it has more to do with class hierarchy.

Nice one to know !!!


Valentin, thankyou for the study !
Clear now about most-specific method !
 
CAUTION! Do not touch the blades on your neck propeller while they are active. Tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic