If you explicitly declare a method both public and final, then nothing prevent you from creating a method in a subclass with the same signature as the private final method in the superclass. You aren't overriding it though, because the subclass knows nothing at all about the private method in the superclass. The subclass method could specify a new return type, or throw new checked exceptions not allowed by the superclass method. It doesn't matter, because the two methods have absolutely nothing to do with each other. At all. The fact that the superclass method is final is irrelevant to the subclass method.
[Note (added later) - the following section is wrong, based on some sloppy thinking on my part. I'd delete it, but then Tony's subsequent post wouldn't make sense. So - please ignore the following except to understand what Tony's talking about.]
For example, the JLS gives rules about compile-time constant expressions which depend in part on whether or not a field is final. So it can become significant to know that
are compile-time constants, but
This probably won't affect anyone's life as much as rules about overriding do - I can't imagine it would be on the exam, for example. But it may help explain why JLS2 22.214.171.124 is worded the way it is. [ January 23, 2005: Message edited by: Jim Yingst ]
There are quite a few errors in this thread that I feel compelled to repair them:
a) a private method cannot be overridden (see below). b) private methods are NOT "final by default". A quick test case can prove this using reflection. c) private int BAR = 2; This is NOT a compile-time constant. The access modifier on a field has no effect on whether it is evaluated at compile-time. JLS 15.28 for more information.
Here's some fun that should clear up your issues:
What is the output? Now change the access modifier on the method printS().
c) private int BAR = 2; This is NOT a compile-time constant.
True, I slipped up there. JLS 126.96.36.199 refers to methods; I erroneously applied it to a field. And a moment's thought reveals other problems - obviously, private fields are mutable; we do it all the time with public setters to private fields. Duh. I've edited my previous post accordingly.
a) a private method cannot be overridden (see below).
b) private methods are NOT "final by default". A quick test case can prove this using reflection.
Interesting - you're right about what reflection says here, at least with the JDK's I've tried. And yet the JLS very clearly states otherwise, as I cited above. Guess this is another example where Sun hasn't ironed out all the details yet. :roll: I see that the proposed JLS3 beta modifies the wording slightly: "A private method and all methods declared immediately within a final class behave as if they were final, since it is impossible to override them". Hmm, that doesn't seem to change the meaning substantially. I suppose "behaves as if final" is a little more vague than "is implicitly final", maybe that gives some wiggle room. Not enough though, in my opinion. Reflection gives different results for a private final method than it does for a private method - thus, the behavior is not the same for both, and is inconsistent with either spec (JLS2 or 3). Maybe if we make some noise about it we can get them to either amend the spec, or fix the bug in their implementation. Unlikely I suppose, but you never know... [ January 23, 2005: Message edited by: Jim Yingst ]
This code is indisputable proof that a private method cannot be overridden, despite any efforts to explain away otherwise (which occurs sometimes). If I tried to explain it on a forum, I'd probably confuse the majority of readers, since it is best explained by the output (as well as the output that differs when the access modifier is altered on the printS method).
I suggest you run it, then change the modifier and run it again, and attempt to follow the path of execution, which is where you will discover that the private method is not overridden. If you have any specific questions, post them here.