通过方法反射向泛型集合添加元素

通常对于泛型集合我们可以先定义需要添加的元素的类型(如int, String, boolean···),这么一来如果我们添加的元素类型跟预先定义的不一样,则编译不会通过。如

// 声明一个数组列表,里面添加的元素只能是 String
ArrayList<string> list = new ArrayList<>();
// 如果添加的元素是其他类型,如 int
list.add(10);

编译阶段就会出现错误

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	The method add(int, String) in the type ArrayList<String> is not applicable for the arguments (int)

但是int类型的数据真的添加不了吗?

可以通过反射来达到这个目的,因为反射进行的操作是编译之后的操作,编译之后集合的泛型是去泛型化的。我们就可以通过方法反射,将要添加的数据添加进入集合

// 获取 list 对象的类类型
Class c = list.getClass();
// 获取 add(Object) 方法
Method m = c.getMethod("add", Object.class);
Object obj = m.invoke(list, 10); // 绕过编译就相当于绕过了泛型

这样一来,数据 10 就被添加到集合中去了。

tips: 调用add方法的时候基本数据类型被自动装箱成其对应的对象类型。所以是可以添加进去的

MethodDemo.java

package com.imooc.reflect;

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

public class MethodDemo4 {
	public static void main(String[] args) {
		ArrayList list = new ArrayList();
		
		ArrayList<String> list1 = new ArrayList<String>();
		list1.add("hello");
		// list1.add(20); 错误的
		Class c1 = list.getClass();
		Class c2 = list1.getClass();
		System.out.println(c1 == c2);
		//反射的操作都是编译之后的操作
		
		/*
		 * c1==c2结果返回true说明编译之后集合的泛型是去泛型化的
		 * Java中集合的泛型,是防止错误输入的,只在编译阶段有效,
		 * 绕过编译就无效了
		 * 验证:我们可以通过方法的反射来操作,绕过编译
		 */
		try {
			Method m = c2.getMethod("add", Object.class);
			m.invoke(list1, 20);//绕过编译操作就绕过了泛型
			System.out.println(list1.size());
			System.out.println(list1);
			/*for (String string : list1) {
				System.out.println(string);
			}*///现在不能这样遍历
		} catch (Exception e) {
		  e.printStackTrace();
		}
	}

}

猜你喜欢

转载自blog.csdn.net/innocent_jia/article/details/89041493
今日推荐