java-classmate icon indicating copy to clipboard operation
java-classmate copied to clipboard

Private methods handled as virtual for inherting classes

Open meszibalu opened this issue 7 years ago • 5 comments

I am using classmate-1.3.3 and I faced with an issue when using MemberResolver. The problem is that if a class and its child class have exactly the same private methods then I cannot access to super class' private method. This behavior is fine when these methods are at least package-private, but private methods do not override each other.

For demonstrating the issue I have attached a simple unit test. In testPrivate() test members.getMemberMethods() should return two functions in my opinion.

InheritanceTest.txt

Best regards, Balazs

meszibalu avatar Feb 01 '17 18:02 meszibalu

@meszibalu Thank you for reporting this. It may take a while for me to look into this but just adding a note to mention I saw this.

I am not 100% sure I understand problem from description, but I assume reproduction explains it.

cowtowncoder avatar Feb 04 '17 01:02 cowtowncoder

Hmmh. I don't think I agree here -- I don't see why both private methods should be reported. What would be use case for doing that? If you want to see private method from parent class, you should probably resolve that (and/or there should be a way to traverse override hierarchy).

It is possible I am missing a use case here so would appreciate help.

cowtowncoder avatar Sep 09 '17 21:09 cowtowncoder

Because private methods do not override each other. Let me give you another example:

public class A {
  private void a() {}
  private void x() {}
}
public class B extends A {
  private void b() {}
  private void x() {}
}

If I resolve B with MemberResolver, then it will return 3 methods. But why 3? B.x does not override A.x, because private methods are not virtual. In my opinion if we return A.a when resolving B, then we should also return A.x, not only B.x.

meszibalu avatar Dec 08 '17 13:12 meszibalu

But there is no real way to call masked base class variant. Except perhaps reflection does allow that. I do see that call dispatching is different from overriding case (which is bit surprising actually) so you are right regarding actual JVM operation.

So I guess my question is really: what is the use case for this?

The reason for my hesitation is that up until this point, uniqueness of signatures (name + arguments + return type) is guaranteed, and conceptually adding both private methods would complicate this part.

cowtowncoder avatar Dec 08 '17 22:12 cowtowncoder

Yes, you are right, reflection allows that, because they are not virtual. For virtual methods, nobody can call the super method.

A possible use case for this: Let's assume that there some beans and bean inheritance is permitted. There are also some lifecycle events like @PostConstruct or @PreDestroy. In this case, we have to name those methods differently, like initializeParentClass(), initializeChildClass(), etc.

I understand your concern, it is quite tricky to handle, and there is a workaround for that if we resolv the members of the base class, so this argument is a little bit theoretical :). This issue also exists for private fields. If you have two private fields with the same name in an inheritance hierarchy, MemberResolver will shadow the field of the parent implementation.

meszibalu avatar Dec 11 '17 10:12 meszibalu