Private methods can not be overridden (private methods are not inherited!) In fact, it makes no difference if you declare a private method final or not.
The two methods you have declared, Boom.touchMe and Boom.Inner.touchMe are two completely separate methods which just happen to share the same identifier. The fact that super.touchMe refers to a different method than touchMe, is just because Boom.Inner.touchMe shadows Boom.touchMe (and not because it overrides it).
This can be demonstrated in a number of ways:
-
As you discovered yourself, if you change the methods to be public, the compiler will complain because you are suddenly trying to override a final method.
-
If you keep the methods private and add the
@Overrideannotation, the compiler will complain. -
As alpian points out, if you cast the
Boom.Innerobject to aBoomobject (((Boom) inner).touchMe()) theBoom.touchMeis called (if it indeed was overridden, the cast wouldn’t matter).
Related question:
- Make private methods final?