反射
概念笔记,具体方法查看API,在线API(https://www.matools.com/api/java8)
1.反射概念
2.反射优点
3.实现基础
4.Class对象三种获取方式
5.拓展:通过反射越过泛型检查
1、反射概念
在程序运行过程中动态的获取类的所有信息,并能创建对象,调用方法,操作属性的一种机制。
(常常会听到映射概念,两者是不同的,映射:映射(Map) ,是一种数据结构,用于存储键值对数据)
2、反射优点
-
反射最突出的优点–灵活(动态编译)
动态编译:在程序运行中,绑定对象。
静态编译:在程序编译时,绑定对象。 -
java为反射的使用,提供了构造方法类(Constructor)、属性类(Field)、方法类(Method),都在java.lang.reflect包下。而java.lang.Class类提供了获取这些类成员对象的方法。
(具体方法查API可知Java 8 中文版 - 在线API中文手册 - 码工具 (matools.com))
3、反射实现基础
反射是通过对应类的类信息对象(java.lang.Class对象)来获取类的所有信息,并执行其他操作。某个类的Class对象是在类加载时被类加载器创建并保存到方法区中。
(类加载器知识笔记-CSDN博客)
4、Class对象的三种获取方式
- 类名.class – Object基类提供的属性
- 对象名.getClass() – Object基类提供的方法
- Class.forName(全限定类名) – java.lang.Class提供的静态方法
(只有第三种比较常用,因为第一中是已知类,完全可以直接创建对象;第二种已经有对象了,更没必要获取类信息(Class)对象了。只有第三种只需要给出全限定类名的字符串,而这个字符串完全可以当做参数传递,更加灵活)
5、拓展:使用反射技术越过泛型检查
(场景:创建一个泛型为String的List集合对象,其add方法只能添加String字符串,但可以通过反射,获取该类的add方法对象,因为List源码中,add方法的参数是Object类型,这样我们就可以通过反射存入其他数据类型的元素了)
public class Practice2 {
public static void main(String[] args) throws Exception {
//1、创建一个存储String类型的List列表
List<String> list = new ArrayList<String>();
list.add("hello everyone!");
//list.add(1);//规定了list集合存放泛型为String,所以报错
//2、通过反射获取ArrayList得add方法
Class<?> c = list.getClass();
Method m_add = c.getDeclaredMethod("add", Object.class);
//获取执行方法权限
m_add.setAccessible(true);
//3、执行方法
m_add.invoke(list, new Animal("变色龙"));
m_add.invoke(list, new Integer(35));
//4、打印集合
System.out.println(list);
}
}
//测试类
class Animal{
String name;
public Animal(String name) {
this.name = name;
}
@Override
public String toString() {
return "Animal [name=" + name + "]";
}
}
运行结果:
可见,Animal类实例和Integer类型实例也存了进来。