[!quote] 反射 反射 允许对成员变量,成员方法,构造方法的信息进行编程访问
- 反射会带来一定的性能开销和安全问题
- 应用例子:idea 里的方法提示,当你输入一个类时,idea 会获取这个类中的方法,然后给你提示
获取
获取的不是 Java 文件,而是 Java 字节码文件 .class
获取 class 对象
Class.forname("全类名")==源代码阶段==使用类名.class==加载阶段==使用对象.getClass();==运行阶段==使用

java
public static void main(String[] args) throws ClassNotFoundException {
Class<?> aClass1 = Class.forName("reflex.Student");
System.out.println(aClass1);
Class<Student> aClass2 = Student.class;
System.out.println(aClass2);
Student s = new Student();
Class<? extends Student> aClass3 = s.getClass();
System.out.println(aClass3);
}[!hint] Java 中,万物皆对象 构造方法的对象
Constructor成员变量的对象field成员方法的对象Method
获取构造方法
Constructor<?>[] getConstructors()返回所有公共构造方法【只包括public】对象的数组Constructor<T> getConstructor(Class<?>... parameterTypes)返回单个公共构造方法对象Constructor<?>[] getDeclaredConstructors()返回所有构造方法Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)返回单个构造方法对象
java
public static void main(String[] args) throws ClassNotFoundException {
Class<?> aClass1 = Class.forName("reflex.Student");
Constructor<?>[] constructors = aClass1.getConstructors();
for (Constructor con : constructors) {
System.out.println(con);
}
// getConstructor
Constructor<?> constructor = aClass1.getConstructor(int.class, String.class);
System.out.println(constructor);
}
---
public reflex.Student()
public reflex.Student(int,java.lang.String)
public reflex.Student(int,java.lang.String)获取成员变量
Field[] getFields()返回所有公共成员变量对象的数组Field[] getDeclaredFields()返回所有成员变量对象的数组Field getField(String name)返回单个公共成员变量对象,name是变量名字Field getDeclaredField(String name)返回单个成员变量对象
java
Class<?> aClass1 = Class.forName("reflex.Student");
Field[] fields = aClass1.getDeclaredFields();
for (Field f : fields) {
System.out.println(f);
}
---
private int reflex.Student.age
private java.lang.String reflex.Student.name作用
- 获取某个对象的成员变量
Field.get(某个对象)
java
Class<?> aClass1 = Class.forName("reflex.Student");
Field name = aClass1.getDeclaredField("name"); // 获取成员变量对象
Student s = new Student(2, "green");
name.setAccessible(true); // 修改 private 的临时权限
String ss = (String) name.get(s); // 获取到 s 对象的 name 变量
System.out.println(ss);
---
green- 修改某个对象的成员变量
Field.set(某个对象,要修改成的值)
java
Class<?> aClass1 = Class.forName("reflex.Student");
Field name = aClass1.getDeclaredField("name");
Student s = new Student(2, "green");
name.setAccessible(true);
String ss = (String) name.get(s);
System.out.println(ss);
// 修改
name.set(s, "red");
String sss = (String) name.get(s);
System.out.println(sss);
---
green
red获取成员方法
Method[] getMethods()返回所有公共成员方法对象的数组【包括父类的所有公共方法】Method[] getDeclaredMethods()返回所有成员方法对象的数组【不包括父类的方法】Method getMethod(String name, Class<?>... parameterTypes)返回单个公共成员方法对象name方法的名称parameterTypes方法的参数类型
Method getDeclaredMethod(String name, Class<?>... parameterTypes)返回单个成员方法对象
java
Class<?> aClass1 = Class.forName("reflex.Student");
Method[] methods = aClass1.getMethods();
for (Method m : methods) {
System.out.println(m);
}
---
public int reflex.Student.getAge()
public void reflex.Student.setAge(int)
public java.lang.String reflex.Student.getName()
public java.lang.String reflex.Student.toString()
public void reflex.Student.setName(java.lang.String)
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()解剖
- 权限修饰符
java
Class<?> aClass1 = Class.forName("reflex.Student");
Constructor<?> constructor = aClass1.getConstructor(int.class, String.class);
int modifiers = constructor.getModifiers();
System.out.println(modifiers);
---
1- 参数
java
Class<?> aClass1 = Class.forName("reflex.Student");
Constructor<?> constructor = aClass1.getConstructor(int.class, String.class);
Parameter[] parameters = constructor.getParameters();
for (Parameter p : parameters) {
System.out.println(p);
}
---
int arg0
java.lang.String arg1- 利用获取到的构造方法创建对象
java
Class<?> aClass1 = Class.forName("reflex.Student");
Constructor<?> constructor = aClass1.getConstructor(int.class, String.class);
Object green = constructor.newInstance(2, "green");
System.out.println(green);
---
Student{age=2, name='green'}- 获取成员变量的类型
Field.getType();
- 获取方法的名字
- 方法的异常
- 方法的参数
- 方法的返回值
java
Class<?> aClass1 = Class.forName("reflex.Student");
Method getName = aClass1.getMethod("getName");
Student s = new Student(2, "李白");
// 使用 invoke 运行方法才能获取到返回值
String invoke = (String) getName.invoke(s);
System.out.println(invoke);
---
李白作用
获取类中的信息:比如获取一个类的信息,写入到某个文件中
结合配置文件,动态的创建对象并调用方法 :
java
// 创建配置文件对象,properties可以看作一个特殊的集合
Properties properties = new Properties();
FileInputStream fileInputStream = new FileInputStream("idea_test//src//prop.properties");
properties.load(fileInputStream);
fileInputStream.close();
String s = (String) properties.get("classname");
String ss = (String) properties.get("method");
System.out.println(s);
System.out.println(ss);
// 再使用反射……
---
reflex.Student
getName强制实例化具有私有构造方法的类 :
java
// 获取其私有构造器
Constructor<Elvis> constructor = Elvis.class.getDeclaredConstructor();
// 将构造器设置为可访问
constructor.setAccessible(true);
System.out.println(constructor.newInstance());
System.out.println(constructor.newInstance());