In my current project, I have classes which are modeled like the following. At some point, a method like getReturnTypeForGetId()
is called on classes A
and B
. Calling the method with A
returns Integer
as expected, but B
returns Serializable
.
What am I missing here? Am I getting bitten by some heinous erasure thing, or am I just missing out on some sort of generic context-clobbering?
EDIT: Adding an over-ridden getId()
method to B
fixes the problem, but I would still like to understand what I am running into.
I've also asked this question on stackoverflow.
import java.io.Serializable; public class WeirdTester { static interface Identifiable<T extends Serializable> { T getId(); void setId(final T id); } static abstract class BaseEntity<T extends Serializable> implements Identifiable<T> { private T id; public T getId() { return id; } public void setId(final T id) { this.id = id; } } static class A implements Identifiable<Integer> { private Integer id; public Integer getId() { return id; } public void setId(final Integer id) { this.id = id; } } static class B extends BaseEntity<Integer> {} @SuppressWarnings("unchecked") private static <T extends Serializable, Q extends Identifiable<T>> Class<T> getReturnTypeForGetId( final Class<Q> clazz) throws Exception { return (Class<T>) clazz.getMethod("getId", (Class[])null).getReturnType(); } public static void main(final String[] args) throws Exception { System.out.println(getReturnTypeForGetId(A.class)); // CONSOLE: "class java.lang.Integer" System.out.println(getReturnTypeForGetId(B.class)); // CONSOLE: "interface java.io.Serializable" } }
Comments