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 )
1) Compiler enumerates all methods in class A and all public methods
in the superclasses of A to find methods named x
a) Why does compiler only look at public methods in superclasses of
A?
It doesn't: It looks at *accessible* methods in A and in
its superclasses. The exact meaning of "accessible" depends
on where the call is: private, package-private (default),
protected, and public grant or deny access based on the relative
"locations" of the call and the potential callee.
b) besides, doesn't compiler also look at methods ( in superclasses of
A ) which have default access specified ( it does on my system )? I
find it strange that author of the book would forget to mention that
Package-private methods of A and its superclasses will be
eligible for consideration if the point of call is in the same
package. If the point of call is in some other package, the
package-private methods are inaccessible and won't be considered.
c) If compiler does look for both default and public methods in A's
superclasses, then why doesn't it also look for methods with protected
access modifier?
Again, it depends on where the call is located. If the call
is inside A, then the protected methods of A's superclasses are
eligible for consideration. If the call is not in the hierarchy
and not in the same package, protected methods are off-limits.
It seems to me you may have missed some precondition in what
the author wrote, like "If a method in class package1.B [page
turn; start reading here] calls a method in package2.A, the
compiler considers the following methods as potential call
targets: ..." Or perhaps the author was sloppy and failed to
explain the circumstances of the call he was trying to elucidate.
I'd suggest a re-read, including a quick look at the preceding
page to see if there's an "In the following discussion" paragraph
that outlines the assumptions.
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 ) ...
3) if method is declared final, static or private then compiler knows
what method to call else ...
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?!
Else the above statement wouldn't make much sense since if method x()
was declared only in one of A's superclasses ( with private access
modifier ), then compiler would report an error and nothing else.
The author is probably trying to point out that some method
calls can be completely resolved at compile time, while others
cannot be fully sorted out until run time. Look at this case
(don't worry about how pointless it seems)
class A {
void m1() { System.out.println("A's m1"}; }
void m2() { m1(); }
}
Inside m2, can the compiler be sure that A's own m1 is called?
No, because the class A might have been extended by some other
class B that overrides m1:
class B extends A {
void m1() { System.out.println("B's m1"); }
}
Now if you create a B instance and call it's m2 method (which
it inherits from A), A's m2 will wind up calling B's m1 instead
of A's own m1. The final determination of whether A's or B's m1
is called cannot be made until run-time, depending on the actual
A-ness or B-ness (or C-ness, or ...) of the object on which m2
is invoked.
But if m1 were final, or private, or static, it could not
be overridden. In this case, the compiler *can* discover
that A's m2 can only call A's m1, and not some other m1.
However, this seems like information someone who's only
been looking at Java for a week probably doesn't need. I'm
not sure why the author of a beginner-level text would burden
you with it.
* 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?!
"Why doesn't the Sun rise in the East?" That is, you *can*
override a protected method. You cannot override it with a
private or package-private method (overriding can loosen the
access restrictions, but cannot tighten them), but you can
override with a protected or public method.
--
Eric Sosman
esosman@ieee-dot-org.invalid