A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

上午看了张老师关于反射获取泛型的实际类型的视频,有些疑问、
         要求,利用反射技术,对于给定的一个集合例如:Vector v; 这个v接收从某个方法放回的对象,里面存储了某种同一类型对象,而我们现在不知道该v中具体的对象类型,现在使用反射技术获取
         张老师的方法是写一个方法 如: public static void applyVector(Vector<Date> vector){ } 其中Date可以为任意对象 ,那么从另外一个方法中来获取这个方法中vector中泛型的参数
代码如下  Method method = Test.class.getMethod("applyVector", Vector.class); //得到给方法类的
                Type[] types= method.getGenericParameterTypes();//得到方法中泛型参数的类型
                ParameterizedType parameterizedType = (ParameterizedType)types[0]; //向下转型
                System.out.println(parameterizedType.getRawType());//得到源类型 即 Vector
                System.out.println(parameterizedType.getActualTypeArguments()[0]);//得到泛型的类型 这里获取的是java.util.Date
说实话对于这个程序疑问还真不少。
第一个:既然要得到v中装的对象的类型,却通过方法得到,说明得到v 之后,我们必须知道获得v的这个方法,这是可以知道,但是如果那个方法不是Vector<Date> vector  而是 Vector vector呢?
也就是说他没有指定泛型,那么这程序是会报错的! 而java是兼容可以不指定泛型的。
第二个:既然我们已经有v这个对象了,如果里面确实存有对象,即v.size() > 0  (等于0就没有必要考虑了,那样是没有任何泛型类型的),为什么我们不直接根据v得到呢?

老师的解释是 通过v.getClass() 是得不到的,这样得到的是Vector的类字节码,而不是里面对象的字节码,确实,
可是有v对象并且在里面有元素的条件下,我们可以先获得里面的元素,再获得元素的字节码,那样不就得到了它的类型么?
代码如下:
             Vector v = new Vector(); //首先定义v,不指定其泛型
             v.add(new Date(System.currentTimeMillis()));//向v中添加对象, 这个v对象可以以任意方式从它出获得,且不知道它里面对象的类型

             System.out.println(v.get(0).getClass().getName()); //在v.size() > 0 的情况下,首先v.get(0)得到其内部元素,这时再getClass()这得到的Class不就是里面元素的Class么,

输出结果:java.util.Date
完全正确,
不知这样的方法可以否,自己从逻辑上推理没有问题。如有问题希望大侠们指正!
完!

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

1 个回复

倒序浏览
按照LZ 想法,我试了一下,既然不知道里面存的到底是什么类型,只知道是相同的类型,那么从其他的途径获得类型,再放到函数里的验证是不合适的,貌似返回的可以是指定泛型,也可以是指定泛型的子类:

public class FanShe {
        public static void main(String[] args) {
                Vector <Number>v = new Vector<Number>();
                v.add(new Integer(8));
                v.add(new Long(1));
        System.out.println(v.get(0).getClass().getName());
        System.out.println(v.get(1).getClass().getName());
        }
}
运行结果:
java.lang.Integer
java.lang.Long
Integer和long同属于Number

而且不可思议的是就算是不同的包,只要是子类就行:

import java.sql.Time;
import java.util.Date;
import java.util.Vector;


public class FanShe {
        public static void main(String[] args) {
                Vector <Date>v = new Vector<Date>();
                v.add(new Time(8));
                v.add(new Date(1));
        System.out.println(v.get(0).getClass().getName());
        System.out.println(v.get(1).getClass().getName());
        }

}
运行结果:
java.sql.Time
java.util.Date
sql中Time是util中Date的子类。

所以老师的方法优势还是很明显的,需要准确的返回泛型还是用老师的吧
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马