文章目录
Java反射机制概述
Reflection(反射)是被视为动态语言的关键,能借助于Reflection API取得任何类的内部信息并能直接操作任意对象的内部属性及方法。
- 正常方式: 引入需要的”包类”名 -> 通过new实例化 -> 取得实例化对象
- 反射方式: 实例化对象 -> getClass()方法 -> 得到完整的“包类”名称
动态语言: 在运行时代码可以根据某些条件改变自身结构。
主要的动态语言:Object-C、C#、JavaScript、PHP、Python、Erlang
静态语言: 运行时结构不可变的语言就是静态语言
主要的静态语言:Java、C、C++。
Java不是动态语言,但Java可以称之为“准动态语言”。
Java反射机制提供的功能:
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时获取泛型信息
- 在运行时调用任意一个对象的成员变量和方法
- 在运行时处理注解
- 生成动态代理
理解Class类并获取Class的实例
通过源码我们可以看到所有类的父类Object中存在一个获取Class对象的方法
public final native Class<?> getClass()
;这就是反射的源头。
Class 类
一个 Class 对象包含了特定某个结构(class/interface/enum/annotation/primitive type/void/[])的有关信息。
- Class本身也是一个类
- Class 对象只能由系统建立对象
- 一个加载的类在 JVM 中只会有一个Class实例
- 一个Class对象对应的是一个加载到JVM中的一个.class文件
- 每个类的实例都会记得自己是由哪个 Class 实例所生成
- 通过Class可以完整地得到一个类中的所有被加载的结构
- Class类是Reflection的根源,针对任何你想动态加载、运行的类,唯有先获得相应的Class对象
Class类的常用方法:
方法名 | 功能说明 |
---|---|
static Class forName(String name) | 返回指定类名 name 的 Class 对象 |
Object newInstance() | 调用缺省构造函数,返回该Class对象的一个实例 |
getName() | 返回此Class对象所表示的实体(类、接口、数组类、基本类型 或void)名称 |
Class getSuperClass() | 返回当前Class对象的父类的Class对象 |
Class [] getInterfaces() | 获取当前Class对象的接口 |
ClassLoader getClassLoader() | 返回该类的类加载器 |
Class getSuperclass() | 返回表示此Class所表示的实体的超类的Class |
Constructor[] getConstructors() | 返回一个包含某些Constructor对象的数组 |
Field[] getDeclaredFields() | 返回Field对象的一个数组 |
Method getMethod(String name,Class … paramTypes) | 返回一个Method对象,此对象的形参类型为paramType |
代码示例:
package demo15;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.stream.Stream;
public class Student extends Person implements Serializable {
public String work;
public String address;
public Student() {
}
public Student(String work, String address) {
this.work = work;
this.address = address;
}
public void study(){
System.out.println("敲代码");
}
public void eat(){
System.out.println("吃饭");
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
// 1. 通过指定类名获取Class对象
Class clazz = Class.forName("demo15.Student");
// 2. 获取一个指定的Class类中的实例
Person person = (Person) clazz.newInstance();
// 3. 获取此Class对象表示的实体名称
System.out.println("3:" + clazz.getName());
// 4. 获取当前Class对象的父类的Class对象
Class superClazz = clazz.getSuperclass();
System.out.println("4:" + superClazz.getName());
// 5. 获取当前Class对象的接口
Class[] interfaces = clazz.getInterfaces();
System.out.print("5:");
Stream.of(interfaces).forEach(System.out::println);
// 6. 获取此类的的类加载器
ClassLoader classLoader = clazz.getClassLoader();
// 7. 获取包含某些Constructor对象的数组
Constructor[] constructors = clazz.getConstructors();
System.out.print("7:");
Stream.of(constructors).forEach(System.out::println