Java课程-034反射
1.反射
反射非常重要,它是动态语言的关键。
动态语言就是不写死,而是根据程序的具体执行情况做出不同的变化。
反射概念很抽象
日常生活中的反射:照镜子可以反射物体的形态
都是通过一个虚像可以映射到一个事物,可以直接获取实物的某些特征。
程序中的反射是通过某些信息(对象、类名 "java.lang.String")可以映射到类,在程序运行期间获取类的相关信息。
反射的工作都是在程序运行期间进行的
反射具体操作简单来说就是在程序运行期间,动态获取类的信息,从而完成某些操作。
常规情况下,是通过类创建对象,反射就是将其进行反转,通过对象来获取类的信息。
1.2.Class 类
Class 类是反射的源头,反射就是获取某些类的信息,抽象出一个对象来表示类的信息,Class 就是用来创建这些对象的类。
Class 的实例化对象是专门用来描述其他类,Class 是专门用来描述其他类的类。
如何获取 Class 的实例化对象?一共有 3 种方式,都跟目标类有关系。
1、通过类名获取
package com.southwind.test;
public class Test {
public static void main(String[] args) throws Exception {
Class aClass = Class.forName("java.lang.String");
System.out.println(aClass);
Class<?> aClass1 = Class.forName("java.io.Serializable");
System.out.println(aClass1);
}
}
2、通过类字面量获取
Class class2 = String.class;
3、通过类的实例化对象获取
Class class3 = str.getClass();
无论通过哪种方式获取的 Class 对象都是同一个,为什么呢?
Java 中的类只会加载一次,加载到 JVM 内存中类叫做“运行时类”,Class 对象就是运行时类映射出来的一个对象。
1.3.获取类的结构
类的结构包括:成员变量、方法、构造函数、继承的父类、实现的接口等等。
Constructor 是 Java 反射包提供的一个类,它的作用是专门用来描述其他类的构造器的,一个 Constructor 实例化对象映射的就是某个类的某个构造函数。
构造器
Class clazz = User.class;
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("*****************************************");
Constructor constructor = clazz.getConstructor();
System.out.println(constructor);
constructor = clazz.getConstructor(Integer.class);
System.out.println(constructor);
constructor = clazz.getConstructor(Integer.class,String.class);
System.out.println(constructor);
System.out.println(new User(1, "a"));
System.out.println(constructor.newInstance(1,"a"));
接口
package com.southwind.test;
public class Test2 {
public static void main(String[] args) {
Class clazz = User.class;
Class[] interfaces = clazz.getInterfaces();
for (Class anInterface : interfaces) {
System.out.println(anInterface);
}
}
}
动态代理机制,给目标类找一个代理去完成工作,代理类不是提前写好的,而是程序运行时动态生成的,动态生成的代理类和目标类肯定是有关联的,代理类必须具备目标类的功能。
Java 中如何描述功能?用接口描述,在动态生成类的时候,需要参照目标类的接口来生成这个动态代理类。
属性(成员变量)
getFields() 方法获取的是类中的公有成员变量(包括从父类继承过来的公有成员变量),public 修饰的
getDeclaredFields() 方法获取的是类中全部成员变量(跟修饰无关,但是不包含父类中的成员变量)
getField(String name) 根据名称获取公有成员变量(包含父类继承过来的)
getDeclaredField(String name) 根据名称获取成员变量(不包含父类继承过来的)
//常规方式
User user = new User();
user.id = 1;
System.out.println(user);
//放射方式
Field id = clazz.getField("id");
id.set(user, 2);
System.out.println(user);
2.视频学习
2.1第一集
2.2第二集
2.3第三集
2.4第四集
版权属于: 依依东望