`
huihui920823
  • 浏览: 36904 次
  • 性别: Icon_minigender_1
  • 来自: 济南
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

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类型,所以会出现类转换异常。



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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics