您的位置:首页 > 其它

认识泛型的本质---反射学习笔记(三)

2015-09-02 15:41 183 查看

package com.test.fanxing;

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

public class FanxingTest {

public static void main(String[] args) {
ArrayList list1 = new ArrayList();
ArrayList<String> list2 = new ArrayList<String>();
list2.add("hello");
//		list2.add(10);//是错误的
Class c1 = list1.getClass();
Class c2 = list2.getClass();
System.out.println(c1==c2);
//反射的操作都是编译之后的操作

/*
* c1==c2结果返回true,说明编译之后集合的泛型是去泛型化的
* Java中集合的泛型,是防止错误输入的,只有在编译阶段有效,绕过编译就无效了
* 验证:我们可以通过方法的反射来操作,绕过编译
*
*/
try {
Method m = c2.getMethod("add", Object.class);
m.invoke(list2, 10);//绕过编译操作就饶过了泛型
System.out.println(list2.size());
System.out.println(list2);
//			for (String string : list2) {
//				System.out.println(string);
//			}//现在不能这样遍历了(因为在list2中有String类型的也有int类型的值)

} catch (Exception e) {
e.printStackTrace();
}
}

}


运行结果:



上边的这段代码分析:

<span style="font-size:18px;">ArrayList<String> list2 = new ArrayList<String>();
list2.add("hello");
//		list2.add(10);//是错误的</span>

list2.add(10);在编译的时候会报错,因为ArrayList<String>集合已经有了String的泛型约束,集合的泛型约束的目的是防止错误输入的。


Class c1 = list1.getClass();
Class c2 = list2.getClass();
System.out.println(c1==c2);
首先因为反射的操作都是编译之后的操作,打印结果为true,表示c1==c2,说明编译之后集合的泛型是去泛型化的,集合的泛型只在编译阶段有效,绕过编译就无效了。就是说当编译完成后,集合的泛型约束就会消失。


Method m = c2.getMethod("add", Object.class);
m.invoke(list2, 10);//绕过编译操作就饶过了泛型
System.out.println(list2.size());
System.out.println(list2);
这段代码的目的是验证---》上边集合泛型只在编译阶段有效,绕过编译就无效了
方法的反射操作是编译之后的操作,是在运行时刻运行的,绕过了编译的过程

打印结果为:

2

[hello, 10]

正好证明了集合的泛型约束真的只是在编译阶段有效,绕过编译就无效了。


for (String string : list2) {
<span style="white-space:pre">	</span>System.out.println(string);
}
这段代码的运行结果为:


原因:

在list2集合中存在:[hello, 10],但是10并不是String类型的,int类型没法转换为String类型,所以会出现类转换异常。



版权声明:本文为博主原创文章,未经博主允许不得转载。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: