0

I want to call a method's super method using reflection, but my method doesn't work, and I'm not sure it's possible. Here's my method to call the super method for the equals(Object) method of class T, which is also called the targetClass here:

private ToBooleanThrowingBiFunction<T> getSuperEquals() {
  Class<T> targetClass = getTargetClass();
  Class<?> superClass = targetClass.getSuperclass();
  while ((superClass != Object.class) && (superClass != null)) {
    try {
      Method method = superClass.getDeclaredMethod("equals", Object.class);
      return (thisOne, thatOne) -> {
        try {
          return (Boolean) method.invoke(thisOne, thatOne);
        } catch (InvocationTargetException e) {
          throw new IllegalStateException(e.getCause());
        }
      };
    } catch (NoSuchMethodException e) {
      superClass = superClass.getSuperclass();
    }
  }
  throw new IllegalArgumentException(String.format("E10: No superclass of %s has an equals() method.", targetClass));
}

@FunctionalInterface
private interface ToBooleanThrowingBiFunction<T>  {
  boolean eval(T thisOne, T thatOne) throws IllegalAccessException;
}

This code correctly extracts a Method that holds the super.equals() method. But when I call it, it executes the equals() method of the targetClass. Is there a way to do this?

MiguelMunoz
  • 4,548
  • 3
  • 34
  • 51
  • 1
    Why do you want to call the super method? What are you actually trying to achieve? Overriding methods is the whole point of OOP. You would have to invoke the method using an *instance* of the super class. – Bohemian Jun 20 '20 at 11:00
  • Is this what you're looking for? https://stackoverflow.com/questions/5411434/how-to-call-a-superclass-method-using-java-reflection – Sabareesh Muralidharan Jun 20 '20 at 11:15
  • Sabareesh Muralidharan: Thanks. I'm going to try that. (But I hate how the MethodHandle.invoke() method is declared to throw Throwable!) – MiguelMunoz Jun 20 '20 at 21:47
  • Bohemian♦ I'm trying to write a tool to generate equals() and hashCode() methods using reflection. I know Apache's EqualsBuilder does this, but I don't like the way they do it. I have a way that will be faster and guarantee that equals() and hashCode() are consistent. But I want to give the users a way to tell their equals code to call the super.equals() method. And I'm not sure that's possible, but I now have a second possible approaches that may work. (I doubt either will work, but I'll try them out first.) – MiguelMunoz Jun 20 '20 at 22:18
  • I tried Sabareesh Muralidharan's suggestion, but it didn't work. I strongly suspect this is simply not possible, but I thought I'd ask. – MiguelMunoz Jun 21 '20 at 12:49
  • 1
    How does you generated `equals` method take place instead of the declared one? In case of Apache’s builders, there is still a declared method calling the builder, so there’s a place where calling `super.equals(…)` is a trivial no-brainer. What about your case? – Holger Jun 22 '20 at 07:37
  • I call it in a static factory method that does all the reflection up front, partly for performance reasons. Except for the invoke method, all the reflection is done once when the class loads. (If you're interested, check out github.com/SwingGuy1024/DogTags. It's not finished yet, but the current version works.) – MiguelMunoz Jun 24 '20 at 03:17

1 Answers1

0

After trying several things, I've concluded that this just isn't possible. (This doesn't surprise me, but I thought I'd give it a shot. I'm often surprised by what you can do through reflection, but you can't do this.)

MiguelMunoz
  • 4,548
  • 3
  • 34
  • 51