2

When implementing a method with a generic return type and reflecting the declared methods on the implementing class, two methods are returned by the reflection API. Ex:

interface Referenceable<T> {
    T getReference();
}

class UUIDRef implements Referenceable<UUID> {
    public UUID getReference() {
      System.out.println("You called");
      return null;
    }
}

@Test
public void test() throws Exception {
    UUIDRef ref = new UUIDRef();
    for (Method m : UUIDRef.class.getDeclaredMethods()) {
      System.out.println(String.format("%s %s", m.getReturnType(), m.getName()));
      m.invoke(ref, null);
    }
}

This outputs:

class java.util.UUID getReference You called class java.lang.Object getReference You called

Why am I getting two methods as having been declared on UUIDRef? Is there any way to accurately learn which of the two is the most refined, having actually been declared on UUIDRef?

Jonathan
  • 5,027
  • 39
  • 48

1 Answers1

2

To support the covariant return type, a bridge method must be created to be able to call the method in code that expects the declared return type.

In short, this bridge method is the method that would be called in the following scenario, where T is erased to Object:

public <T> T doSomething(Referenceable<T> obj) {
   return obj.getReference();
}

Use m.isBridge() to tell which is the bridge method.

Community
  • 1
  • 1
Mark Peters
  • 80,126
  • 17
  • 159
  • 190