您的位置:首页 > 编程语言 > Java开发

Java反射(六)----- 通过反射了解集合泛型的本质

2016-06-17 20:01 591 查看
java中的泛型是JDK5中引入的新特性,允许在定义类和接口的时候使用类型参数,声明的类型参数在使用时用具体的类型来替换,泛型最主要是应用在集合类框架中。下面我们通过反射来进一步理解泛型的本质。

先放上示例代码

MethodDemo4.java文件

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class MethodDemo4 {
public static void main(String[] args) {
//该list1中可以放任何类型
ArrayList list1 = new ArrayList();
//该list2中只能放String类型
ArrayList<String> list2 = new ArrayList<>();

list1.add("hello");
list2.add("hello");
//list2.add(20);    //错误
Class c1 = list1.getClass();
Class c2 = list2.getClass();
System.out.println(c1 == c2);       //结果 true(说明编译之后的集合的泛型是去泛型化的)

//反射的操作都是运行时操作,即编译之后的操作

//java中集合的泛型是防止错误输入的e,只在编译阶段有效,通过编译就无效了

//通过方法的反射来绕过编译进行验证
try {
Method m = c2.getMethod("add", Object.class);
//注意:在上面的list2中时只能放入String类型,此处通过反射加入int类型100
m.invoke(list2, 100);
System.out.println(list2.size());       //运行结果为2,说明100被成功添加进list2
System.out.println(list2);      //运行结果  [hello, 100]      (此时不能通过for/foreach来遍历,会报类型错误)
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

}


代码中,集合list1中可以放入任何类型,但集合list2中只能放入String类型,我们通过反射绕过编译之后,成功在list2中加入int类型的100,可看出,在编译之后,集合List已经没有了类型限制,这种情形称为类型擦除。List在前面指定类型只是为了防止错误输入,以便在编译时可以及时发现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: