package demo;
import java.lang.reflect.Method;
import java.util.ArrayList;
/**
* 3、 ArrayList<Integer> list = new ArrayList<Integer>();
* 在这个泛型为Integer的ArrayList中存放一个String类型的对象。
*
* 涉及知识点:
* 1、泛型相关知识
* 2、通过反射获取并调用对象的方法
*
* 思路:
* 1、无法向泛型为Integer的ArrayList中添加一个String类型对象,因为ArrayList只接受Integer类型。
* 2、想要接受不同泛型的数据,那就要靠反射跳过泛型,调用ArrayList类中的add方法的接收String类型对象。
* 3、具体先通过list对象获取类,再反射获取add方法,通过反射添加数据
*
* 总结:
* 1、泛型,就是在方法上对于接受的类型进行了一个限定,JDK 1.5版本以后出现的新特性,用于解决安全问题,是一个安全机制。
* a、将运行时期出现的问题ClassCastException,转移到了编译时期,方便于程序员解决问题,让运行时期问题减少,提高安全性。
* b、避免了强制转化的麻烦。
* 2、要注意反射的对象被修饰的修饰符是什么:
* a、如果是public修饰的,可以直接getMethod();
* b、如果是默认的,就需要通过getDeclaredMethod();
* c、若是private,必须通过暴力反射,就是要通过getDeclaredMethod(),并设置setAccessible(true)来进行设置权限。
*
* 思考:
* 1、泛型规范了元素的存储,提高了安全性。可是通过反射,就可以轻易地打破这个规范。
* 2、反射尽管让程序变得便捷,但也让程序变得不安全,因此要慎用反射。
* */
public class demo03 {
//用反射跳过泛型,调用 ArrayList类中的add方法添加String
public static void main(String[] args) throws Exception{
ArrayList<Integer> list = new ArrayList<Integer>();
String str="I'm a String";
Integer i = 7;
Method m = list.getClass().getMethod("add", Object.class);//得到add方法对象
//利用正常方式添加Integer类型的对象
list.add(i);
//利用反射的方式添加
m.invoke(list, i);
//正常方法没法添加泛型不符合的对象
//list.add(str);
//利用反射的方法则可以添加
m.invoke(list, str);//通过反射来执行list的第一个方法,第一个是list对象,代表该对象的方法,第二个是方法参数
for (Object obj : list) {
System.out.println(obj);
}
}
} |
|