运行时获取接口泛型类型实例

148 阅读1分钟
public class MyTest {
    public static void main(String[] args) throws IOException {
        Test test = new Test();
        test.print1();
        test.print2();
        test.print3();
    }

    public static class Test implements
            Interface3<Vector,TreeSet>,
            Interface1<ArrayList, LinkedList, CopyOnWriteArrayList>,
            Interface2<HashSet, LinkedHashMap, HashMap>
    {
    }


    public interface Interface3<A,B>{
        default void print3() {
            A a = newInstance(getClass(), Interface1.class, 0);
            B b = newInstance(getClass(), Interface1.class, 1);

            System.out.println("Interface3.A="+a+",B="+b);
        }
    }
    public interface Interface2<A,B,C>{
        default void print2() {
            A a = newInstance(getClass(), Interface1.class, 0);
            B b = newInstance(getClass(), Interface1.class, 1);
            C c = newInstance(getClass(), Interface1.class, 2);

            System.out.println("Interface2.A="+a+",B="+b+",C="+c);
        }
    }
    public interface Interface1<A extends List,B,C>{
        default void print1() {
            A a = newInstance(getClass(), Interface1.class, 0);
            a.add(1);
            a.add(2);
            a.add(3);

            B b = newInstance(getClass(), Interface1.class, 1);
            C c = newInstance(getClass(), Interface1.class, 2);

            System.out.println("Interface1.A="+a+",B="+b.getClass().getSimpleName()+",C="+c.getClass().getSimpleName());
        }
    }


    /**
     * 运行时获取接口泛型类型实例
     * <pre class="code">
     * public interface Interface3<A,B,C>{
     *    default void print3() {
     *         System.out.print("Interface3.A="+newInstance(getClass(), Interface3.class, 0).getClass().getSimpleName());
     *         System.out.print(",B="+newInstance(getClass(), Interface3.class, 1).getClass().getSimpleName());
     *         System.out.println(",C="+newInstance(getClass(), Interface3.class, 2).getClass().getSimpleName());
     *     }
     * }
     * </pre>
     * @param aClass 接口实现类的Class ->(在接口中通过getClass()方法获取到的是实现类的Class)
     * @param interfaces 接口  ->  (实现类可能实现多个接口,因此要指定接口)
     * @param index 获取接口的第几个泛型  ->  (接口在)
     * @param <T>
     * @return
     */
    public static <T> T newInstance(Class<?> aClass,Class interfaces,int index){
        try {
            Type[] types = aClass.getGenericInterfaces();
            for (Type type : types) {
                if (type instanceof ParameterizedType) {
                    ParameterizedType pti = (ParameterizedType) type;
                    Type rawType = pti.getRawType();
                    if (rawType.equals(interfaces)) {
                        Type ata = pti.getActualTypeArguments()[index];
                        return (T) ((Class) ata).getDeclaredConstructor().newInstance();
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(),e.getCause());
        }
        return null;
    }
}