Assignment #1: Reflection and equals

Implement a class with the public static method shown below. You may add private helpers as you see fit.

package cop4338;

public class Utilities
{
    public static boolean equals( Object lhs, Object rhs );
}

The equals Method

This method is meant to be usable by anyone. The specification of equals is as follows:
  1. If both lhs and rhs are null, equals returns true.
  2. If exactly one of lhs and rhs is null, equals returns false.
  3. Otherwise, both lhs and rhs are not null. If either lhs or rhs has an equals method defined (NOT INHERITED) you must call it and return its result. Use getDeclaredMethod to find if equals exists.
  4. (ADDED JAN 11): Otherwise, if either lhs or rhs has an equals method that is inherited and this method is marked final, you must call it and return its result. Use getMethod to find if this equals exists.
  5. Otherwise, you will use reflection to construct an equals method for lhs. In the reflective equals method:
    1. If lhs and rhs have different class types, return false.
    2. Otherwise, for each data field in lhs, if the corresponding data field in rhs is not equal return false. Note that you will need to allow access to private data by using setAccessible. Each field is tested as follows:
      1. Declared (not inherited) primitive fields use ==.
      2. Declared (not inherited) reference fields use Utilities.equals. EXTRA CREDIT PART:This may result in infinite recursion if an object contains a cyclic reference to itself. To avoid this problem, keep a shared ArrayList that stores a list of reference variables whose equals call is pending. (Use add when you agree to enter a recursive call, remove when you exit the recursive call, and use a sequential search prior to agreeing to enter the recursive call, since contains will not work.) If you detect a cycle, return false.
      3. If the superclass of lhs defines equals, use it to test the entire set of inherited fields. Otherwise, test only the fields declared by the immediate superclass using the methodology shown above, and then repeat this process for each superclass on the path back to Object until you find a superclass that has provided an equals method.

What to Submit

Submit all of your source code and the result of running a significant set of test examples that illustrate all of the cases above, including the possibility of a cycle of references. Part of your grade will be based on the completeness of your test cases.