Noname's Blog
信息安全专业的小萌新,立志走上更大的舞台
Java反射

Java反射

通过反射,可以在程序运行时访问Java对象的属性、方法和构造函数等

为什么要有反射
让开发人员可以通过外部类的路径名来创建对象,且可以枚举出类的全部成员
测试时可以用反射API类的私有成员,可以保证测试的代码覆盖率

应用场景
开发通用框架
动态代理
注解
可扩展性功能 -- 插件

反射机制

类加载过程

java文件编译成class文件

加载 (类加载器)生成java.lang.Class对象

连接

本质
在运行时,把Java类中的各种成文映射成一个个的Java对象

使用

Class对象

核心类

获取class对象

Student stu = new Student();

//方法1
Class  stuClass1 = stu.getClass();
System.out.println(stuClass1);//class com.fanshe.Student 获得类的完整路径

//方法2
Class stuClass2 = Student.class;

//方法3
//好处:不用依赖于对象类,不需要导包
Class stuClass = null;
stuClass = Class.forName("com.reflect.Student");//类的全称

Construct类

获取Constructor构造函数
提供构造函数的信息和访问构造函数的接口

newInstance 生成新的对象实例
setAccessible 更改访问级别(用于访问私有对象时)

获取公共构造函数 getConstructors

for(Constructor cons : stuClass.getConstructors())
{
    ...
    System.out.println(cons);
}

获取所有构造函数,包括私有的 getDeclaredConstructors

for(Constructor cons : stuClass.getDeclaredConstructors())
{
    System.out.println(cons);
}

通过参数获取对应构造函数 getConstructor
获取无参构造

Construct cons = null;
cons = stuClass.getConstructor(null);
//生成对象
Object obj = cons.newInstance();

获取有参构造函数

cons = stuClass.getConstructor(String.class);//获取String类型的
//生成对象
Object obj = cons.newInstance("ccc");

若要获取私有类型的构造函数 getDeclaredConstrucotor

con = stuClass.getDeclaredConstructor("ccc");

//生成对象时要暴力提升访问级别
cons.setAccessible(true);
Object obj = cons3.newInstance("ccc");

Field类

提供一个类的域的信息以及访问类的域的接口
获取属性列表
获取public属性列表

for(Field field : stuClass.getFields())
{
    System.out.println(field);
}

获取所有属性列表

for(Field field : stuClass.getDeclaredFields())
{
    System.out.println(field);
}

获取单独属性

Field field = stuClass.getField("classNo");
field.get(obj);//取出obj对象实例中的classNo值

获取私有属性

Field field = stuClass.getDeclaredField("stuNo");
field.setAccessible(true);
field.get(obj);

获取父类的成员属性

Field field = stuClass.getSuperClass().getDeclaredField("name");
field.setAccessible(true);
field.get(obj);

设置成员属性

field.setAccessible(true);
field.set(obj, "hhh");
field.get(obj);

Method类

提供一个类的方法的信息,以及访问类的方法的接口

获取所有的public方法
父类以及父类的父类至最顶级的Object的public方法、public静态方法

for(Method method : stuClass.getMethods())
{
    System.out.println(method);
}

获取所有的方法
获取到定义在该类里的方法,不包括父类的

for(Method method : stuClass.getDeclaredMethods())
{
    System.out.println(method);
}

获取指定方法

Method method = stuClass.getMethod("method", String.class);//(方法名,参数类型列表)
//调用方法
method.invoke(obj, "ccc");

获取私有方法

Method method = stuClass.getDeclaredMethod("method", String.class);
System.out.println(method);
method2.setAccessible(true);
method2.invoke(obj, "歪歪歪");

获取静态方法

Method method = stuClass.getDeclaredMethod("method";
System.out.println(method);
Object result = method.invoke(obj);
System.out.println(result);

其他

Member接口 反映单个成员(字段或者方法)或者构造函数的标识信息
Modifier类 提供了static方法和常量,对类和成员访问修饰符进行解码
Proxy类 提供动态生成代理类和类实例的静态方法