文章目录
- 反射是什么?
- 反射的作用
- 所有方法汇总
- 一、加载Class对象
- 二、加载类的构造器对象
- 三、加载类的成员变量
- 四、加载类的成员方法
反射是什么?
反射就是:加载类,并允许以编程的方式解剖类中的某个成分(成员变量,方法,构造器等)
反射需要学什么
- 反射第一步:加载类,获取类的字节码:Class对象
- 获取类的构造器:Constructor对象
- 获取类的成员变量:Field对象
- 获取类的成员方法:Method对象
在反射中,最重要的就是Class对象,之后的一切操作都是根据Class对象来操作的
反射的作用
-
基本作用:可以得到一个类的全部成分然后操作
-
可以破坏封装性
-
适合做Java的框架,主流的框架会基于反射设计出一些通用的功能
一下测试代码我只提供了一个方法,需要源代码的在这里:反射代码
所有方法汇总
一、加载Class对象
获取Class对象的三种方法
- Class c1 = 类名.class
- 调用Class提供方法:public static Class forName(String Package);
- Object提供的方法:public Class getClass(); Class c3 = 对象.getClass();
/*** 测试三种方式得到的Class的三种方法* @throws ClassNotFoundException*/@Testpublic void testEquals() throws ClassNotFoundException {Class s1 = Class.forName("com.wk.reflect.Student");Class s2 = Student.class;Student student = new Student();Class s3 = student.getClass();System.out.println(s1 == s2); //trueSystem.out.println(s2 == s3); //trueSystem.out.println(s1 == s3); //true}
二、加载类的构造器对象
加载构造器对象的步骤:
- 获取类的Class对象
- 调用方法获得构造器对象
- 使用:创建一个对象实例newInstance()
获取构造器的方法如下
方法 | 说明 |
---|---|
Constructor<?>[] getConstructors() | 获取全部构造器(只能获取public修饰) |
Constructor<?>[] getDeclaredConstructors() | 获取全部构造器(任意修饰都可以拿到) |
Constructor getConstructor(Class<?>… parameterTypes) | 获取某个构造器(只能能获取public修饰) |
Constructor getDeclaredConstructor(Class<?>… parameterTypes) | 获取某个构造器(任意修饰都可以拿到) |
Constructor提供的方法 | 说明 |
---|---|
T newInstance(Object… initargs | 调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回 |
public void setAccessible(boolean flag) | 设置为True,表示禁止加内存访问控制(暴力反射) |
@Testpublic void testAll() throws Exception {//获得一个Class对象Class<Student> s1 = Student.class;//获取一个构造器//这里将无参构造器设置为private的,但是这个也可以获取Constructor<Student> constructor = s1.getDeclaredConstructor(); //无参构造器是private的,所以需要暴力反射constructor.setAccessible(true); Student stu = constructor.newInstance();System.out.println(stu);}
--------------输出---------------
无参构造器执行...
Student{age=0, name='null'}
三、加载类的成员变量
加载成员变量对象的步骤:
- 获取类的Class对象
- 调用方法获得成员变量对象
- 使用:调用成员变量对象的get()/set()方法
获取构成员变量的方法如下
方法 | 说明 |
---|---|
public Field[] getFields() | 获取类的全部成员变量(只能获取public修饰的) |
public Field[] getDeclaredFields() | 获取类的全部成员变量(任意修饰都可以拿到) |
public Field getField(String name) | 获取类的某个成员变量(只能获取public修饰的) |
public Field getDeclaredField(String name) | 获取类的某个成员变量(任意修饰都可以拿到) |
方法 | 说明 |
---|---|
void set(Object obj, Object value); | 赋值 |
Object get(Object obj) | 取值 |
public void setAccessible(boolean flag) | 设置为true,表示禁止检查访问控制(暴力反射) |
@Testpublic void testAllField() throws Exception {Class<Student> student = Student.class;//单个时输入变量名Field age = student.getDeclaredField("age");Student student1 = new Student();age.setAccessible(true);age.set(student1,18);System.out.println(student1);}
------------输出--------------
无参构造器执行...
Student{age=18, name='null'}
四、加载类的成员方法
加载成员方法对象的步骤:
- 获取类的Class对象
- 调用方法获得成员方法对象
- 使用:调用成员方法对象的invoke()方法
方法 | ||
---|---|---|
Method[] getMethods() | 获取类的全部成员变量(只能获取public修饰的) | |
Method[] getDeclaredMethods() | 获取类的全部成员变量(任意修饰都可以拿到) | |
Method getMethod(String name, Class<?>… parameterTypes) | 获取类的某个成员变量(只能获取public修饰的) | |
Method getDeclaredMethod(String name, Class<?>… parameterTypes) | 获取类的某个成员变量(任意修饰都可以拿到) |
Mehode提供的方法 | 说明 |
---|---|
public Object invoke(Object obj, Object… args) | 触发某个对象的该方法执行 |
public void setAccessible(boolean flag) | 设置为true,表示禁止检查访问控制(暴力反射) |
@Testpublic void testAllMethod() throws Exception {Class<Animal> animal = Animal.class;//参数为方法的名称Method declaredMethod = animal.getDeclaredMethod("eat");declaredMethod.setAccessible(true);Animal animal1 = new Animal();Object invoke = declaredMethod.invoke(animal1);//返回值为nullSystem.out.println(invoke);}
-----------输出--------------
动物吃
null
完结~