- 1. 反射的概念
- 2. 获取Class对象的三种方式
- 3. Class类的方法
- 4. 反射案例
- 5. 参考资料
将类的各个组成部分封装成其他对象,这就是反射机制。
Java代码的运行阶段
源代码阶段->Class对象阶段->运行阶段
图片来源 黑马Java零基础入门到就业_Java基础(IDEA版本)
将Person.class文件封装成Class对象的过程就是反射。
反射的好处:
- 可以在程序运行过程中,操作这些对象。
- 可以解耦,提高程序的扩展性。
- Class.forName("类的全限定名") :将字节码文件加载到内存。
- 类名.class :通过类名.属性 获取Class对象。
- 对象名.getClass() :通过调用Object.getClass方法 获取Class对象。
package reflect_test;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
Class> aClass1 = Class.forName("reflect_test.Test");
Class testClass = Test.class;
Class extends Test> aClass = new Test().getClass();
System.out.println(aClass1.hashCode());
System.out.println(testClass.hashCode());
System.out.println(aClass.hashCode());
}
}
注: 同一个.class文件在程序运行中,只会被加载一次,堆中只有一个Class对象。
3. Class类的方法获取字段
| 方法 | 作用 |
|---|---|
| public Field getField(String name) | 根据字段名获取public修饰的字段对象 |
| publice Field[] getFields() | 获取public修饰的字段对象 |
| publice Field getDeclaredField(String name) | 根据字段名获取字段对象 |
| publice Field[] getDeclaredFields() | 获取所有字段对象 |
| Filed类的方法 | 作用 |
|---|---|
| publice set(Object obj,Object value) | 给obj对象的字段赋值 |
| publice get(Object obj) | 获取对象obj的字段值 |
| publice void setAccessible(boolean flag) | 不是公共的要开启暴力反射,才能获取、设置值 |
获取构造器
| 方法 | 作用 |
|---|---|
| publice Constructor getConstructor(Class>… parameterTypes) | 获取public修饰的构造器 |
| publice Constructor>[] getConstructors() | 获取所有public修饰的构造器 |
| publice Constructor getDeclaredConstructor(Class>… parameterTypes) | 获取构造器 |
| publice Constructor>[] getDeclaredConstructors() | 获取所有构造器 |
| Constructor类的方法 | 作用 |
|---|---|
| public T newInstance(Object … initargs) | 创建对象,也可以直接用Class对象.newInstance()方法创建对象 |
| public void setAccessible(boolean flag) | 开启暴力反射 |
获取方法
| Method类的方法 | 作用 |
|---|---|
| public Method getMethod(String name, Class>… parameterTypes) | 获取public修饰的方法,参数是方法名,参数列表 |
| pulic Method[] getMethods() | 获取所有public方法 |
| public Method getDeclaredMethod(String name, Class>… parameterTypes) | 获取方法,参数是方法名,参数列表 |
| public Method[] getDeclaredMethods() | 获取所有方法 |
| Method类的方法 | 作用 |
|---|---|
| public Object invoke(Object obj, Object… args) | 执行ojb对象的方法,方法参数是args |
| public void setAccessible(boolean flag) | 开启暴力反射 |
使用反射创建任意对象,执行任意方法。
实现代码
package reflect_test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class CustomFramework {
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
//1.
//2.
Properties properties = new Properties();
properties.load(new FileInputStream("methods.properties"));
String className = properties.getProperty("className");
String method = properties.getProperty("method");
//3.
Class> clazz = Class.forName(className);
//4.
Object o = clazz.newInstance();
//5.
Method m = clazz.getMethod(method);
m.invoke(o);
}
}
配置文件
className=reflect_test.Person method=method
注: 不改代码,只改配置文件,更易扩展。许多框架的配置文件中使用全类名其实都是用的反射。
5. 参考资料黑马Java零基础入门到就业_Java基础(IDEA版本)



