对泛型了解不错,请教大家一个问题
public class Father<T>
{
Class<T> clazz;
public Father()
{
clazz = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public void t()
{
System.out.print(clazz);
}
}
public class Test1 extends Father<java.lang.Integer>
{
public Test1()
{
System.out.println(clazz);
} public static void main(String[] args)
{
Test1 t = new Test1();
}
}
public class Test2{
public Test2()
{
System.out.println(clazz);
} public static void main(String[] args)
{
Father<任意数据类型> a = Father<>(任意数据类型);
}
}上面两个类,那Test1需要在继承Father的时候指定T的类型,然后可以返回,没有问题。
但这样test1就做的比较死板,我希望可以Father<任意数据类型> a = Father<>(任意数据类型),这样可以动态
但Test2这样做的话就会报错java.lang.ClassCastException,就是在clazz = (Class<T>) 做转换的时候出错
请问,应该怎么写才对呢?谢谢!

解决方案 »

  1.   


    Test2的main函数怎么没有new关键字的呢?
      

  2.   

    Father <Object> 这样就可以
      

  3.   

    public class Test2{ 
    public static void main(String[] args) 

    Father <T> a = new Father <T>;
    a.t();} 

    这样可以不
      

  4.   

    刚才贴的Test2有误,重贴
    public class Test2 {
    public static void main(String[] args) {
    Father<Object> f = new Father<Object>(1);  
    f.t();
    }
    }
      

  5.   

    没明白你在问什么 LZ发代码可以先用Code自己套起来 然后自己先写出个例子么? 
      

  6.   

    Father <Object>   用这个吧。
      

  7.   


    class Test1<T> extends Father<T> {
    public Test1() {
    System.out.println(clazz);
    } public static void main(String[] args) {
    Test1<Test2> t = new Test1<Test2>();
    }
    }
      

  8.   

    to BearKin:这样写一样会报java.lang.ClassCastException:异常to taozhaocailiu:希望能写个示例代码,你这样发一句有什么用
      

  9.   

    只有改成extends Father<Test2>才ok,但这样就不灵活了啊
      

  10.   

    /**  
         * 通过反射,获得指定类的父类的泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport<Buyer>  
         *  
         * @param clazz clazz 需要反射的类,该类必须继承范型父类
         * @param index 泛型参数所在索引,从0开始.  
         * @return 范型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code>
         */  
        @SuppressWarnings("unchecked")
    public static Class getSuperClassGenricType(Class clazz, int index) {    
            Type genType = clazz.getGenericSuperclass();//得到泛型父类  
            //如果没有实现ParameterizedType接口,即不支持泛型,直接返回Object.class   
            if (!(genType instanceof ParameterizedType)) {
                return Object.class;   
            }  
            //返回表示此类型实际类型参数的Type对象的数组,数组里放的都是对应类型的Class, 如BuyerServiceBean extends DaoSupport<Buyer,Contact>就返回Buyer和Contact类型   
            Type[] params = ((ParameterizedType) genType).getActualTypeArguments();                   
            if (index >= params.length || index < 0) { 
              throw new RuntimeException("你输入的索引"+ (index<0 ? "不能小于0" : "超出了参数的总数"));
            }      
            if (!(params[index] instanceof Class)) {
                return Object.class;   
            }   
            return (Class) params[index];
        }试试这个工具类好使不?
      

  11.   

    楼主 可以参考 泛型http://blog.csdn.net/bluesmile979/archive/2009/03/10/3976905.aspx
    http://www.ibm.com/developerworks/cn/java/j-djc02113/
    http://www.fh888.com/showfile.html?articleid=51203542FC8943AE9D3B91C7FA4F5507&projectid=5&username=yhn
      

  12.   

    package com;import java.lang.reflect.ParameterizedType;public class Father<T>
    {
    Class<T> clazz; public Father()
    {
    clazz = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }
    public Father(int pint)
    {
    clazz = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }
    public void t()
    {
    System.out.print(clazz);
    }
    }package com;public class Test1 extends Father<Integer>
    {
    public Test1()
    {
    System.out.println(clazz);
    } public static void main(String[] args)
    {
    Test1 t = new Test1();
    }
    }package com;public class Test2 { public static void main(String[] args) {
    Father<Object> f = new Father<Object>(1);  
    f.t();
    }
    }
    说明:1、test1方法在继承的时候在继承的时候指名数据类型,这样感觉比较死
          2、test2方法在实例化的时候指定类型,但会报错java.lang.ClassCastException
    谢谢!
      

  13.   

    将father改下:
    package test;import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;public class Father<T> {
    Class<T> clazz; public Father() {
    // clazz = (Class<T>) ((ParameterizedType) this.getClass()
    // .getGenericSuperclass()).getActualTypeArguments()[0];
    } public Father(int pint) {
    Type genType = this.getClass().getGenericSuperclass();//得到泛型父类
    if (!(genType instanceof ParameterizedType)) { 
    clazz = (Class<T>) genType.getClass();  
            }  else {
             clazz = (Class<T>) ((ParameterizedType) this.getClass()
         .getGenericSuperclass()).getActualTypeArguments()[0];
            }

    } public void t() {
    System.out.print(clazz);
    }
    }
      

  14.   

    public class Father <T> { 
        Class entityClass; 
        public Father() { 
            Type gType = this.getClass().getGenericSuperclass();  //-----这一句,麻烦看看API再看看与你的
             //Test2 测试有什么区别?你的Test2测试根本没有经过父类吧;
            entityClass = (Class) ((ParameterizedType)gType).getActualTypeArguments()[0]; 
        } 
        public void t() { 
            System.out.print(entityClass.getName()); 
        } 

    本身泛型在运行时是不会存在的,即 Type Erasure (Google看头条),至于 getGenericSuperclass()如何获得了运行时的泛型我也不知道怎么弄的,看不到源代码(即使看到也看不懂^_^,JVM...JVM...); 我想了想,看了下 ArrayList 中的源码,其用来存储的数组是 Object 而获取存储的时候是进行了强转的,可以说在运行时还是Object,并且其没有代码(反射等等)操作到那个泛型 E,完全是按照规范的泛型语法在用。最后,我想如果可以按照你Test2测试的那样使用的话,Hibernate Wiki 上的 Generic Data Access Objects 也不会这么写了吧;
      

  15.   

    楼上代码
    运行Test2的时候,Father<Integer> f = new Father<Integer>(1); 
    不管是什么类型的对象,都输出
    java.lang.Class
    而不是Father<Integer> f = new Father<Integer>(1); 输出class java.lang.Integer
    这个可以解决吗?谢谢!
      

  16.   


    那个 int 不是泛型啊, 是你构造方法指定的值类型- -||
      

  17.   


    看错了- -, 你可以看看 TypeVariable 的 API, 看能不能够理解点,我不使用继承,直接那类上的泛型
    this.getClass().getParameterTypes() 拿回来的是 T.....  TypeVariable 则代表着这个可变的 T
      

  18.   

    再说清楚点,我就是希望可以通过定义一个类public class Father<T>
    然后在另外一个类里实例化 Father <Integer> f = new Father <Integer>
    最后可以在Father中得知T的数据类型是Integer
    不知道说清楚了没有
      

  19.   

    来个简单的吧:
    public class Test2<T>   {

    Class<T> clazz;  
      
        @SuppressWarnings("unchecked")  
        public Test2(Class<T> clazz)  
        {  
            this.clazz = clazz;  
            System.out.println(clazz);  
        }  
        
        @SuppressWarnings("unchecked")  
        public Test2(int pint)  
        {  
        
            this.clazz = (Class<T>) new Integer(pint).getClass();  
            System.out.println(clazz);  
        }  
      
       public static void main(String[] args)  
        {  
            Test2<Integer> t = new Test2<Integer>(Integer.class);  
            Test2<String> t1 = new Test2<String>(String.class);  
            Test2<Integer> t2 = new Test2<Integer>(1);  
        }  


    }
      

  20.   

    [CODE]
    public class Top<T> {
        public Top() {
            for(TypeVariable d : this.getClass().getTypeParameters()) {
                System.out.println(d.getName()); // 这个拿不到想要的- -||
            }
        }
    }public class Test {
        public void test(){
            Top<Integer> top = new Top<Integer>();
        }
    }
    [/CODE]
    这是我的测试代码
      

  21.   

    啊啊啊, Code 标签不能使用啊
    public class Top<T> {
        public Top() {
            for(TypeVariable d : this.getClass().getTypeParameters()) {
                System.out.println(d.getName());
            }
        }
    }public class Test {
        public void test(){
            Top<Integer> top = new Top<Integer>();
        }
    }
      

  22.   

       就用Father<Object>
      

  23.   

    /**  
        * 通过反射,获得指定类的父类的泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport <Buyer>  
        *  
        * @param clazz clazz 需要反射的类,该类必须继承范型父类 
        * @param index 泛型参数所在索引,从0开始.  
        * @return 范型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回 <code>Object.class </code> 
        */  
        @SuppressWarnings("unchecked") 
    public static Class getSuperClassGenricType(Class clazz, int index) {    
            Type genType = clazz.getGenericSuperclass();//得到泛型父类  
            //如果没有实现ParameterizedType接口,即不支持泛型,直接返回Object.class  
            if (!(genType instanceof ParameterizedType)) { 
                return Object.class;  
            }  
            //返回表示此类型实际类型参数的Type对象的数组,数组里放的都是对应类型的Class, 如BuyerServiceBean extends DaoSupport <Buyer,Contact>就返回Buyer和Contact类型  
            Type[] params = ((ParameterizedType) genType).getActualTypeArguments();                  
            if (index >= params.length || index < 0) { 
            throw new RuntimeException("你输入的索引"+ (index <0 ? "不能小于0" : "超出了参数的总数")); 
            }      
            if (!(params[index] instanceof Class)) { 
                return Object.class;  
            }  
            return (Class) params[index]; 
        } 试试这个工具类好使不?