flying3615
12/11/2018 - 4:29 AM

Reflection of generic mixed with inheritance test

Reflection of generic mixed with inheritance test

import java.lang.reflect.ParameterizedType;

public class GenericTest {

    public static void main(String[] args) throws Exception {
        GenericService<Foo, String> fooGs = new FooService();
        System.out.println(fooGs.keyToLife()+" expect to be Love");

        GenericService<Bar, Integer> barGs = new BarService();
        System.out.println(barGs.keyToLife()+" expect to be 42");
    }
}

abstract class GenericService<T extends Answer, R> {

    abstract R keyToLife() throws Exception;

    T getInstanceOfT() throws Exception {
        ParameterizedType superClass = (ParameterizedType) getClass().getGenericSuperclass();
        Class<T> type = (Class<T>) superClass.getActualTypeArguments()[0];
        Class<R> returnType = (Class<R>) superClass.getActualTypeArguments()[1];
        System.out.println("Get instance type="+type.getSimpleName()+" and method return type="+returnType);
        return type.newInstance();
    }
}

class FooService extends GenericService<Foo, String> {
    String keyToLife() throws Exception {
        Answer<String> foo = getInstanceOfT();
        return foo.sayAnswer();
    }
}

class BarService extends GenericService<Bar, Integer> {
    Integer keyToLife() throws Exception {
        Answer<Integer> bar = getInstanceOfT();
        return bar.sayAnswer();
    }
}

interface Answer<R> {
    R sayAnswer();
}


class Foo implements Answer<String> {
    @Override
    public String sayAnswer() {
        return "Love";
    }
}

class Bar implements Answer<Integer> {
    @Override
    public Integer sayAnswer() {
        return 42;
    }
}