Skip to content

AnnotatedMember.equals() does not work reliably #3187

@klaasdellschaft

Description

@klaasdellschaft

Hi,

I noticed some strange behavior of the current AnnotatedMember.equals() implementations. Following test case for AnnotatedConstructor.equals() currently fails:

public void testAnnotatedConstructorEquality() {
    ObjectMapper mapper = new ObjectMapper();
    DeserializationConfig context = mapper.getDeserializationConfig();
    JavaType beanType = mapper.constructType(SomeBean.class);

    AnnotatedClass instance1 = AnnotatedClassResolver.resolve(context, beanType, context);
    AnnotatedClass instance2 = AnnotatedClassResolver.resolve(context, beanType, context);

    // Successful
    assertEquals(instance1, instance2);
    assertEquals(instance1.getDefaultConstructor().getAnnotated(), instance2.getDefaultConstructor().getAnnotated());
    
    // Fails
    assertEquals(instance1.getDefaultConstructor(), instance2.getDefaultConstructor());
}

Based on the first two successful assertEquals(...) statements, I would have expected that the third assertEquals(...) should be also successful. However, it currently fails.

The reason for this behavior is that AnnotatedConstructor.equals() is currently using == for comparing the two constructors:

public boolean equals(Object o) {
    if (o == this) return true;
    return ClassUtil.hasClass(o, getClass())
            && (((AnnotatedConstructor) o)._constructor == _constructor);
}

However, the implementation of the reflection API in java.lang.Class is always copying / cloning the Field, Method and Constructor instances prior to returning them to the caller (e.g. see Class.copyConstructors()). Thus, each call of Class.getConstructors() will always return new instances.

If you agree that the above test case should be successful (i.e. also assertEquals(instance1.getDefaultConstructor(), instance2.getDefaultConstructor()) should be successful), I would prepare a corresponding pull request that slightly modifies the current implementation of the equals() method for all subclasses of AnnotatedMember that are affected by this problem (i.e. at least AnnotatedField, AnnotatedConstructor and AnnotatedMethod).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions