2

I have this interface:

interface MyInt<T> {

    public void foo(T t);
}

And these classes:

class MyString implements MyInt<String> {

    @Override
    public void foo(String t) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

}

class MyDouble implements MyInt<Double> {

    @Override
    public void foo(Double t) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

}

Now I want to test if a class not only implements MyInt (i can do that), but if that class implements MyInt<String>, my code so far:

Class<MyInt> c = MyInt.class;
Class c0 = MyString.class;
Class c1 = MyDouble.class;

System.out.println(c.isAssignableFrom(c0)); //true
System.out.println(c.isAssignableFrom(c1)); //true

Every try for adding the String "sublass" (dont even know correct name for T) result in compilation error. Any way to do this?

Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
kajacx
  • 12,361
  • 5
  • 43
  • 70
  • You should be able to add a getter to MyInt which returns the class of T. `public Class getImplementedClass() { return T.getClass(); }` – Bob Dalgleish Jun 12 '13 at 13:41
  • @BobDalgleish `MyInt` is an interface. You can not add method implementations to an interface. You would need to do it in each implementing class which makes the whole approach useless. – Andreas Fester Jun 12 '13 at 13:49

1 Answers1

2

I want to test if a class not only implements MyInt, but if that class implements MyInt<String>

You might wanted to do something like

Class<MyInt<String> > c = MyInt<String>.class;

but this is not possible due to type erasure. See Java: how do I get a class literal from a generic type? for a very good explanation.

To still be able to check whether your class implements an interface which uses some specific type, you can retrieve the generic type arguments of a given class and check the type of it:

Class c0 = MyString.class;
Class c1 = MyDouble.class;

ParameterizedType c0Type = (ParameterizedType) c0.getGenericInterfaces()[0];
Class<?> type0Class = (Class<?>) c0Type.getActualTypeArguments()[0];

ParameterizedType c1Type = (ParameterizedType) c1.getGenericInterfaces()[0];
Class<?> type1Class = (Class<?>) c1Type.getActualTypeArguments()[0];

System.out.println(type0Class.isAssignableFrom(String.class));  // true
System.out.println(type1Class.isAssignableFrom(String.class));  // false

This should work for your particular case. You need to adjust the array indexes when you are implementing more than one interface and/or using more than one generic type parameter.

Community
  • 1
  • 1
Andreas Fester
  • 36,091
  • 7
  • 95
  • 123