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

© 谢洋 高级黑马   /  2013-3-10 21:44  /  10158 人查看  /  29 人回复  /   6 人收藏 转载请遵从CC协议 禁止商业使用本文

public static void main(String[] args){
      //因为编译后就就把泛型类限定去掉了,通过反射获取泛型的参数类型
      //Vector<Date> v1 = new Vector<Date>();
      Method applyMethod = GenericTest.class.getMethod("applyVector",Vector.class);2、//通过从字节码中得到Method对应的方法,这里已经没有<Date>这个信息了
     //可能有多个参数,
     Type[] types=applyMethod.getGenericParameterTypes();
     ParameterizedType pType = (ParameterizedType)types[0];
     //取得原始参数
     System.out.println(pType.getRawType());//class java.util.Vector
    //取得实际类型参数
    System.out.println(pType.getActualTypeArguments()[0]);//class java.sql.Date//3、既然编译后<Data>被去掉了,这里怎么又能拿到?
}
public static void applyVector(Vector<Date> v1){//编译后<Date>信息被去掉
  
}
//编译后相当于
public static void applyVector(Vector v1){//1、编译后已把<Date>信息被去掉
  
}
老师张老师在讲解加强中泛型讲的中示例:
为什么编译后泛型类型参数被去后,通过反射却还可以得到?
反射不是从字节码中得到类相应的成分?而字节码是编译后的东西,是没有泛型信息的,这怎么搞的?

评分

参与人数 1技术分 +2 收起 理由
admin + 2 这问题很多人问过,我下面回复你.

查看全部评分

29 个回复

正序浏览
学习的好深入,解释也很详细清楚,受教了!
回复 使用道具 举报
反射的3个阶段。1.源文件阶段Class clazz = class.forName("类名")2.字节码阶段Class clazz = Person.class  3.创建对象阶段Class clazz = P.getclass();
回复 使用道具 举报
好强大
回复 使用道具 举报
学习了,希望我以后也能来解答。{:2_36:}
回复 使用道具 举报
相当于讲解。。明白了!
回复 使用道具 举报
路漫漫其修远兮~
回复 使用道具 举报
学习了!
回复 使用道具 举报
好东西呀。我在想我怎么没这样的疑问,理解不够呀。废话少说,好好学吧!
回复 使用道具 举报
谢谢,老师的讲解
回复 使用道具 举报
java没学啊。
回复 使用道具 举报
技术分!!!!!!!!!!!
回复 使用道具 举报
基础很重要啊,继续学习中
回复 使用道具 举报
感觉好深啊。。。看来还得慢慢学习。。。
回复 使用道具 举报
为自己加油 ,!
回复 使用道具 举报
霸道了,这个要学…
回复 使用道具 举报
师兄们,小弟学习学习
回复 使用道具 举报
admin 程序媛 2013-3-11 10:57:30
13#
mingning179 发表于 2013-3-11 02:44
关于 ArrayList arr = new ArrayList();

第一,如果不对ArrayList这个类做任何改变,你是无法在程序中得 ...


第1、2点表述正确。声明泛形的类中是没有具体类型信息的,使用时才会赋予具体类型,也就是使用者类中(也就是class文件中)会有具体类型的声明。看来咱们的讨论的确存在信息不对称,我指的是泛形类本身,而你指的是赋值的那个类(这种使用者类我在概念上归于运行时)。怪我没细看你的问题。


回复 使用道具 举报
admin 发表于 2013-3-11 00:19
你可以做一个实验,写一个类A和B,如下:

package com.itheima.bean;

看到你这么解说,我似乎有上点明白,下面是我的对泛型运行的理解,不知这样解释行不行得通
1、以前笔记记下的个人的理解:
既然泛型是给编译器看的,编译后的代码也是确定,也没有泛型信息,那不同类型的实参调用同一份代码是怎么做到?我想是编译在编译时根据实际被不同类型实参调用,就会生成相对应不同的多份代码,这样子程序员只写一份,就可以达到被不同类型的参数调用。这样做好像行得通,但不确实不合理,生产的代码太垃圾,sun公司不可能这样子做吧
2、现在的理解:
根据你所说的以及上面代码执行的效果来看:
a、先首编译给根据被定义了泛型的成分上的泛型信息保存到字节码中的一部分(这里可以说是被编译器看的),然后把去掉泛型信息的源代码编译成字节码中的另一部分(类)。
b、那这两部分是怎么联系起来的?我想泛型信息那部分会以某种方式记住某些成分是始何被定义的,当我们调用实参时,JVM会根据传
过来的实参信息及调用那个成分(应该是地址,这样才能找到相应成分),再到字节码中泛型信息部分查找正在被调用的成分的泛型是如何被定义的,
再根据找泛型信息及实参匹配到正被调用的成分上,也就是说在执行的时才能确定参数类型。
c、另我认为实应用了泛型的成分,编译后是没法确定的参数类型,因为编译根本都没知道参数是什么类型的;
虽然泛信息和类的信息在字节码中是分开的,但这时生成类那部分的代码与普通的代码还是有区别的,那就是普通代码本身就有参数类型信息,而应用泛型的代码没有。
d、最后,如果我上面的理解是正确的,那么这我认为“泛型是给编译器看的,”这句话不是很准确,但为了便于学习,我觉得这么说还是行得通的。

如理解有误之处,强烈希望更正!!
回复 使用道具 举报
学习了,希望以后还有类似的问题时候也能得到解答啊。
回复 使用道具 举报
学习了,管理员的讲解很形象,引申:JAVA中遇到的知识点必须要牢牢掌握 黑马必备
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马