Re: Why does compiler only look at public methods of superclasses
of...?
failure_to@yahoo.co.uk wrote:
Hello
I haven't been learning Java for the past week or so, but now that I
finally got back to it, I decided to refresh on few things I
previously learned and thus the following questions about dynamic
binding came to be:
Say we have class A reference variable called a. According to my book,
when a.x() is called, the following steps take place ( I won't write
all the steps taken ( or at least not in detail ), but just the ones
that relate to my questions )
The exact sequence is defined in JLS 3, ?15.12. The full steps probably
fills up a dozen or so pages, most of which are solely for generic and
variable-argument methods. Since I am assuming generic and variadic
method lookups are not in question here, I will excise that from my
response.
1) Compiler enumerates all methods in class A and all public methods
in the superclasses of A to find methods named x
The book is wrong. JLS 3 clearly states:
The class or interface determined by compile-time step 1 (?15.12.1) is
searched for all member methods that are potentially applicable to this
method invocation; members inherited from superclasses and
superinterfaces are included in this search.
The compiler would limit this methods to those that are potentially
applicable:
# The name of the member is identical to the name of the method in the
method invocation.
# The member is accessible (?6.6) to the class or interface in which the
method invocation appears.
# The arity of the member is lesser or equal to the arity of the method
invocation.
# If the member is a fixed arity method with arity n, the arity of the
method invocation is equal to n.
[ Variable-argument and generics points are removed from this list; the
full list is at ?15.12.2.1 ]
The correct statement should be:
Compiler enumerates all accessible methods in class A and the
superclasses and superinterfaces to find methods named x with the right
number of arguments.
2) In the next step compiler determines the types of parameters
supplied in the parameter call and finds exact or best match ( this
process is called overloading resolution ) ...
JLS 3 specifies several phases (but still one step). Roughly:
Phase 1: Method is still probably applicable if the types of the formal
parameters are subtypes are convertible from the expression type of the
parameters.
Phase 2: Same thing with a different type of convertibility
Phase 3: Variable-argument resolution
Phase 4: Pick the most specific method
3) if method is declared final, static or private then compiler knows
what method to call else ...
I am assuming that this is supposed to be step 3 according to the JLS,
which finds out all of the information:
# The name of the method.
# The qualifying type of the method invocation (?13.1).
# The number of parameters and the types of the parameters, in order.
# The result type, or void.
# The invocation mode, computed as follows:
* If the compile-time declaration has the static modifier, then the
invocation mode is static.
* Otherwise, if the compile-time declaration has the private
modifier, then the invocation mode is nonvirtual.
* Otherwise, if the part of the method invocation before the left
parenthesis is of the form super . Identifier or of the form
ClassName.super.Identifier then the invocation mode is super.
* Otherwise, if the compile-time declaration is in an interface,
then the invocation mode is interface.
* Otherwise, the invocation mode is virtual.
Most of the method resolution ("what method to call") comes from the
runtime resolution process. The JVM spec governs this part of the process.
Why point out that if method is private then compiler knows what
method to call? I'm assuming that book is only talking about the case
where private method x() is defined in class A and not in one of A's
superclasses?!
It should be obvious why private methods are non-virtually called. I
think the book is trying to summarize the JLS but is inaccurately
representing in the process.
* This may be a silly question, but why can't you override a protected
method? Surely there is some very good reason for java developers
deciding not to allow this?!
Sure you can. Specifically from the JLS:
If the overridden or hidden method is protected, then the overriding or
hiding method must be protected or public; otherwise, a compile-time
error occurs.
--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth