Java语言中,想通过反射实例化一个抽象类的子类,问题也可以简化点,可以建个类继承这个抽象类,然后实例化子类。public abstract class MyClass<T> {
    MyClass() {
    }} 在代码中可以这么写:new MyClass<String>() {}但是如果通过反射,怎么把String这个type传进去,或者通过反射获得constructor,怎么把泛型信息传进去下面这个是个错误的写法,只是说明要实现的内容: new MyClass<Class.forName("String")>() {
}

解决方案 »

  1.   

    理解了java泛型的擦除,很多问题就解决了,这是一个例子:
    class MyClass<T> {    private Class<T> classType;    public MyClass(Class<T> classType) {
            this.classType = classType;
        }    public T getClassType() {
            try {
                return classType.newInstance();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
      

  2.   

    在另一个帖子刚回复了,复制一份到这里for example
    import java.lang.reflect.*;
    public class Test {
        static class A<T> {
            T t;        public void test() {
                System.out.println(t);
            }
        }    static class B<T> {
            T t;
            public B(T t) {this.t = t;}        public void test() {System.out.println(t);}
        }    public static void main(String[] args) throws Throwable {
            Class<?> c = A.class;
            Object o = c.newInstance();
            Method m = c.getDeclaredMethod("test");
            m.invoke(o);
            
            c = B.class;
            Constructor con = c.getDeclaredConstructor(new Class[]{Object.class}); //用Object.class代替T
            o = con.newInstance(new Object[]{"bbb"});
            m = c.getDeclaredMethod("test");
            m.invoke(o);
        }
    }
      

  3.   

    基本原理理解了,但是实际操作还是有些问题。我再把问题具体一下:在使用jackson从json转换成bean时,需要传递类信息。
    ObjectMapper mapper = new ObjectMapper();
    String jackson1 = "json格式的字符串,略";
    List<ClassA> list = mapper.readValue(jackson1, new TypeReference<ArrayList<ClassA>>(){});
    String jackson2 = "json格式的字符串,略";
    ClassB list = mapper.readValue(jackson2, new TypeReference<ClassB>(){});现在想通过反射的方式,构造TypeReference子类的实例。但是TypeReference中的_type是final并且不可访问,而且传递的类型又有可能是泛型,所以一时还没调通。各位再帮忙看看,我也再试试楼上各位的方法。package org.codehaus.jackson.type;import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;/**
     * This class is used to pass full generics type information, and
     * avoid problems with type erasure (that basically removes most
     * usable type references from runtime Class objects).
     * It is based on ideas from
     * <a href="http://gafter.blogspot.com/2006/12/super-type-tokens.html"
     * >http://gafter.blogspot.com/2006/12/super-type-tokens.html</a>,
     * Additional idea (from a suggestion made in comments of the article)
     * is to require bogus implementation of <code>Comparable</code>
     * (any such generic interface would do, as long as it forces a method
     * with generic type to be implemented).
     * to ensure that a Type argument is indeed given.
     *<p>
     * Usage is by sub-classing: here is one way to instantiate reference
     * to generic type <code>List&lt;Integer></code>:
     *<pre>
     *  TypeReference ref = new TypeReference&lt;List&lt;Integer>>() { };
     *</pre>
     * which can be passed to methods that accept TypeReference.
     */
    public abstract class TypeReference<T>
        implements Comparable<TypeReference<T>>
    {
        final Type _type;    protected TypeReference()
        {
            Type superClass = getClass().getGenericSuperclass();
            if (superClass instanceof Class<?>) { // sanity check, should never happen
                throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");
            }
            /* 22-Dec-2008, tatu: Not sure if this case is safe -- I suspect
             *   it is possible to make it fail?
             *   But let's deal with specifc
             *   case when we know an actual use case, and thereby suitable
             *   work arounds for valid case(s) and/or error to throw
             *   on invalid one(s).
             */
            _type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
        }    public Type getType() { return _type; }    /**
         * The only reason we define this method (and require implementation
         * of <code>Comparable</code>) is to prevent constructing a
         * reference without type information.
         */
        @Override
        public int compareTo(TypeReference<T> o) {
            // just need an implementation, not a good one... hence:
            return 0;
        }
    }
      

  4.   

    用你的TypeReference代码作了一下测试,没什么问题啊,报什么错了?
    import java.util.*;
    public class Test {
        static abstract class TypeReference<T> implements Comparable<TypeReference<T>> {
            final Type _type;        protected TypeReference() {
                Type superClass = getClass().getGenericSuperclass();
                if (superClass instanceof Class<?>) { // sanity check, should never happen
                    throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");
                }
                /* 22-Dec-2008, tatu: Not sure if this case is safe -- I suspect
                 *   it is possible to make it fail?
                 *   But let's deal with specifc
                 *   case when we know an actual use case, and thereby suitable
                 *   work arounds for valid case(s) and/or error to throw
                 *   on invalid one(s).
                 */
                _type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
            }        public Type getType() { return _type; }        /**
             * The only reason we define this method (and require implementation
             * of <code>Comparable</code>) is to prevent constructing a
             * reference without type information.
             */
            @Override
            public int compareTo(TypeReference<T> o) {
                // just need an implementation, not a good one... hence:
                return 0;
            } 
        }    public static void main(String[] args) throws Throwable {
            TypeReference<ArrayList<String>> tr = new TypeReference<ArrayList<String>>() {};
            System.out.println(tr.getType());
            System.out.println(tr.compareTo(new TypeReference<ArrayList<String>>(){}));
        }
    }
      

  5.   

    TypeReference这个类没问题,我是想把下面这行改成反射调用
    List<ClassA> list = mapper.readValue(jackson1, new TypeReference<ArrayList<ClassA>>(){});是不是ArrayList<ClassA>我提前是不知道的,是通过配置文件读的,也可能是ArrayList<ClassB>等等。
      

  6.   

    LZ你的这段代码并没有用到反射
    抽象类是不能直接实例化的,所以你是怎么用反射实例化的?
    可以通过继承抽象类的匿名类来反射生成和匿名类相同的对象
    import java.util.*;
    public class Test {
        static abstract class TypeReference<T> implements Comparable<TypeReference<T>> {
            final Type _type;        protected TypeReference() {
                Type superClass = getClass().getGenericSuperclass();
                if (superClass instanceof Class<?>) { // sanity check, should never happen
                    throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");
                }
                /* 22-Dec-2008, tatu: Not sure if this case is safe -- I suspect
                 *   it is possible to make it fail?
                 *   But let's deal with specifc
                 *   case when we know an actual use case, and thereby suitable
                 *   work arounds for valid case(s) and/or error to throw
                 *   on invalid one(s).
                 */
                _type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
            }        public Type getType() { return _type; }        /**
             * The only reason we define this method (and require implementation
             * of <code>Comparable</code>) is to prevent constructing a
             * reference without type information.
             */
            @Override
            public int compareTo(TypeReference<T> o) {
                // just need an implementation, not a good one... hence:
                return 0;
            } 
        }
        @SuppressWarnings("unchecked")
        public static void main(String[] args) throws Throwable {
            TypeReference<List<String>> tr = new TypeReference<List<String>>(){}; //先生成一个匿名类实例
            Class<?> c = tr.getClass(); //取得匿名类的Class对象
            Constructor con = c.getDeclaredConstructor(new Class[0]); //取得构造方法
            con.setAccessible(true);
            TypeReference<List<String>> o = (TypeReference<List<String>>)con.newInstance(new Object[0]); //生成和匿名类一样的对象
            System.out.println(o.getType());
            System.out.println(o.compareTo(tr));
        }
    }
      

  7.   


    static class B<T> {
            T t;
            public B(T t) {this.t = t;}        public void test() {System.out.println(t);}
        }按照这种方式构造一个T类型是ArrayList<ClassA>的B的实例,是不是要先构造一个T类型是ClassA的ArrayList实例,这样是不是嵌套了。
      

  8.   

    这条路走不通的,泛型参数既然是动态,为何不直接用TypeReference<Object>子类
    抽象类不能直接反射实例化的,需要继承它的子类,而你的泛型参数又是动态的,根本就没法确定这个子类,如果非要这样做,那就自己写一堆的if else来对应吧,比如
    import java.util.*;
    public class Test {
        static abstract class TypeReference<T> implements Comparable<TypeReference<T>> {
            final Type _type;        protected TypeReference() {
                Type superClass = getClass().getGenericSuperclass();
                if (superClass instanceof Class<?>) { // sanity check, should never happen
                    throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");
                }
                /* 22-Dec-2008, tatu: Not sure if this case is safe -- I suspect
                 *   it is possible to make it fail?
                 *   But let's deal with specifc
                 *   case when we know an actual use case, and thereby suitable
                 *   work arounds for valid case(s) and/or error to throw
                 *   on invalid one(s).
                 */
                _type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
            }        public Type getType() { return _type; }        /**
             * The only reason we define this method (and require implementation
             * of <code>Comparable</code>) is to prevent constructing a
             * reference without type information.
             */
            @Override
            public int compareTo(TypeReference<T> o) {
                // just need an implementation, not a good one... hence:
                return 0;
            } 
        }
        @SuppressWarnings("unchecked")
        public static void main(String[] args) throws Throwable {
            TypeReference<?> tr = null;
            String className = "java.util.ArrayList<java.lang.String>"; //假设是这样的泛型参数
            //String className = "java.lang.String";
            List<String> cnList = new ArrayList<String>(); //解析泛型参数结果集
            if (className.matches("[^<>]*?<.*?>")) { //如果包含多个泛型参数,则解析每一层参数
                cnList.add(className.substring(0, className.indexOf("<")));
                String sub = className.substring(className.indexOf("<")+1, className.lastIndexOf(">"));
                while (sub.contains("<")) {
                    cnList.add(sub.substring(0, sub.indexOf("<")));
                    sub = sub.substring(sub.indexOf("<")+1, sub.lastIndexOf(">"));
                }
                cnList.add(sub);
            } else {
                cnList.add(className);
            }        if (cnList.size() == 1) {//如果只有1层泛型参数
                Class<?> c = Class.forName(cnList.get(0));
                if (c == String.class) { //判断是什么类型的参数,生成相应的子类对象
                    tr = new TypeReference<String>(){};
                } else if (c == Integer.class) { //so on
                    tr = new TypeReference<Integer>(){};
                } else { 
                    tr = new TypeReference<Object>(){};
                }
            } else if (cnList.size() == 2) { //有2层泛型参数
                Class<?> c1 = Class.forName(cnList.get(0));
                Class<?> c2 = Class.forName(cnList.get(1));
                if (List.class.isAssignableFrom(c1)) { //先判断第1层泛型参数
                    if (c2 == String.class) { //再判断第2层泛型参数
                        tr = new TypeReference<List<String>>(){}; //生成相应的子类实例
                    } else if (c2 == Integer.class) {
                        tr = new TypeReference<List<Integer>>(){};
                    } else {
                        tr = new TypeReference<List<Object>>(){};
                    }
                } else if (Set.class.isAssignableFrom(c1)) { //so on
                    if (c2 == String.class) {
                        tr = new TypeReference<Set<String>>(){};
                    } else if (c2 == Integer.class) {
                        tr = new TypeReference<Set<Integer>>(){};
                    } else {
                        tr = new TypeReference<Set<Object>>(){};
                    }
                } else {
                    tr = new TypeReference<Object>(){};
                }
            } else {//泛型参数太多,直接简化为用Object
                tr = new TypeReference<Object>(){};
            }        System.out.println(tr.getType());
            Class<?> c = tr.getClass(); //取得子类对象的Class对象
            //use reflect to create instance //接下来就可以用c通过反射来生成实例了
             TypeReference<?> o = (TypeReference<?>)c.newInstance();
            System.out.println(o.getType()); 
        }
    }