jeudi 19 avril 2018

Java reflection to call overloaded method Area.equals(Area)

As discussed in this question, the equals method of java.awt.geom.Area is defined as

public boolean equals(Area other)

instead of overriding the equals method from Object. That question covers the "why", and I'm interested in "how can I force Java to use the most appropriate equals method".

Consider this example:

public static void main(String[] args) {
    Class<?> cls = Area.class;
    Area a1 = new Area(new Rectangle2D.Double(1, 2, 3, 4));
    Area a2 = new Area(new Rectangle2D.Double(1, 2, 3, 4));
    System.out.println("Areas equal: " + a1.equals(a2)); // true

    Object o1 = (Object) a1;
    Object o2 = (Object) a2;
    System.out.println("Objects equal: " + o1.equals(o2)); // false

    // Given only cls, o1, and o2, how can I get .equals() to return true?
    System.out.println("cls.cast() approach : " + cls.cast(o1).equals(cls.cast(o2))); // false

    try {
        Method equalsMethod = cls.getMethod("equals", cls); // Exception thrown in most cases
        System.out.println("Reflection approach: " + equalsMethod.invoke(o1, o2)); // true (when cls=Area.class)
    } catch (Exception e) {
        e.printStackTrace();
    }
}

My question is: given o1, o2, and cls, where o1 and o2 are guaranteed to be instances of cls (or a subclass), how can I call the most appropriate equals method? Some examples:

  • when cls is Area.class, I want to call Area.equals(Area), since Area overloads Object's equals
  • when cls is Rectangle2D.class, I want to call Rectangle2D.equals(Object), since Rectangle2D overrides Object's equals
  • when cls is Path2D.class, I want to call Object.equals(Object), since Path2D doesn't override/overload any equals

In principle, I could use reflection to check for each of the above method signatures, but that seems pretty heavy-handed. Is there a simpler way?





Aucun commentaire:

Enregistrer un commentaire