11

Is there a way to find out if a class has overriden equals() and hashCode() ?

Jabir
  • 2,776
  • 1
  • 22
  • 31

2 Answers2

22

You can use reflection

public static void main(String[] args) throws Exception {
    Method method = Bar.class.getMethod("hashCode" /*, new Class<?>[] {...} */); // pass parameter types as needed
    System.out.println(method);
    System.out.println(overridesMethod(method, Bar.class));
}

public static boolean overridesMethod(Method method, Class<?> clazz) {
    return clazz == method.getDeclaringClass();
}

class Bar {
    /*
     * @Override public int hashCode() { return 0; }
     */
}

will print false if the hashCode() is commented out and true if it isn't.

Method#getDeclaringClass() will return the Class object for the class where it is implemented.

Note that Class#getMethod(..) works for public methods only. But in this case, equals() and hashCode() must be public. The algorithm would need to change for other methods, depending.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • Important note: I didn't realize this until I looked it up, but `getMethod("hashCode")` doesn't simply return a method named `hashCode`; it returns a method named `hashCode` **with no parameters**. `getMethod` takes a varargs list of `Class>` parameters that must match the method's parameters, and if there are no such parameters, it only matches methods with zero parameters. That isn't obvious from the code above, and I thought it was flawed (if the class declares a `hashCode` with parameters) until I looked it up. – ajb Feb 26 '14 at 04:25
  • Refinement: The OP didn't say what should happen if class `A` overrides `equals` and `hashCode`, and class `B` extends `A` but doesn't override them. If the desired result is still `true` (since it's not using the `Object` defaults), change `clazz == method.getDeclaringClass()` to `Object.class != method.getDeclaringClass()`. [But I haven't tested.] – ajb Feb 26 '14 at 04:28
  • @ajb For your refinement, that would be the way to do it. In that case, there would be no need to pass the target `Class`. – Sotirios Delimanolis Feb 26 '14 at 04:34
  • I have problems getting your code to work for `equals`, I get a `NoSuchMethodException` ...is there another way to test for overridden equals? – ycomp Nov 09 '17 at 03:17
  • it's runnable at [here](https://www.jdoodle.com/a/deF) , I get the same problem with other code in my project based on this answer as well.. hashCode works fine. I have java 8 – ycomp Nov 09 '17 at 04:07
  • @ycomp `equals` has a single parameter of type `Object`. You need to mention that when you use `getMethod`. So `getMethod("equals", Object.class)`. – Sotirios Delimanolis Nov 09 '17 at 04:09
2

to check if a method is declared in your class you can use the following code.

System.out.println(C.getMethod("yourMethod").getDeclaringClass().getSimpleName());

here you can find the name of the declaring class.

So check using the code in your subclass to check if equals or hasCode method. And match if the declaring class name is same as your desired class

stinepike
  • 54,068
  • 14
  • 92
  • 112
  • I'd prefer to use `==` on the class, rather than trying to match the name, just in case someone with a perverse sense of humor names a nested or inner class `Object`. – ajb Feb 26 '14 at 04:27