Java反射(learning)
Java - reflection
Java反射(Reflection)是Java语言的一个特性,它允许程序在运行时检查和修改内部类的行为。通过反射,可以获取类的构造器、方法、字段等成员的信息,并且可以动态地创建对象、调用方法、访问和修改字段。
Java反射主要涉及到以下几个类:
java.lang.Class
:代表一个类,每个类都有一个与之对应的Class
对象。可以通过.class
语法或Class.forName()
等方法获取一个类的Class
对象。java.lang.reflect.Constructor
:代表一个类的构造器,通过它可以动态创建类的实例。java.lang.reflect.Method
:代表一个类的方法,通过它可以动态调用类的方法。java.lang.reflect.Field
:代表一个类的字段,通过它可以动态访问和修改类的字段。
0. 实体类Car
package org.spring6Demo.reflect;
public class Car {
private String brand;
private String color;
private int price;
// no param constructor
public Car() {
}
// private constructor
private Car(String brand, int price) {
this.brand = brand;
this.price = price;
}
// public params_constructor
public Car(String brand, String color, int price) {
this.brand = brand;
this.color = color;
this.price = price;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
private void run() {
System.out.println("private method run()");
}
@Override
public String toString() {
return "Car{" +
"brand='" + brand + '\'' +
", color='" + color + '\'' +
", price=" + price +
'}';
}
}
1. 获取类的Class对象
@Test
public void test01() throws Exception {
// 类名.class
Class<Car> carClass1 = Car.class;
// 对象.getClass()
Class<? extends Car> carClass2 = new Car().getClass();
// Class.forName(全路径)
Class<?> carClass3 = Class.forName("org.spring6Demo.reflect.Car");
// 实例化
Car car = (Car) carClass3.getDeclaredConstructor().newInstance(); // 默认无参构造
System.out.println(car);
}
2. 获取构造函数
// 获取构造方法
@Test
public void test02() throws Exception {
Class<Car> carClass = Car.class;
// 获取所有构造方法
Constructor<?>[] constructors1 = carClass.getConstructors(); // 仅能获取到public constructor
for (Constructor<?> c : constructors1) {
System.out.println(c.getName() + " Modifier:" + modifiers_to_String(c.getModifiers()) + " params:" + Arrays.toString(paramsClass_to_String(c.getParameterTypes())));
} // org.spring6Demo.reflect.Car Modifier:public params:[String, String, int]
System.out.println("=============================================");
Constructor<?>[] constructors2 = carClass.getDeclaredConstructors(); // 可获取到所有声明了的constructor
for (Constructor<?> c : constructors2) {
System.out.println(c.getName() + " Modifier:" + modifiers_to_String(c.getModifiers()) + " params:" + Arrays.toString(paramsClass_to_String(c.getParameterTypes())));
} // org.spring6Demo.reflect.Car Modifier:private params:[String, int]
System.out.println("=============================================");
// 指定使用有参构造实例化
// public constructor
Constructor<Car> constructor1 = carClass.getConstructor(String.class, String.class, int.class);
Car car1 = constructor1.newInstance("BWM", "white", 500000);
System.out.println(car1);
System.out.println("=============================================");
// private constructor
Constructor<Car> constructor2 = carClass.getDeclaredConstructor(String.class, int.class);
constructor2.setAccessible(true); // 设置可以访问私有构造
Car car2 = constructor2.newInstance("Benz", 450000);
System.out.println(car2);
}
3. 获取属性
@Test
public void test03() throws Exception {
Class<?> carClass = Car.class;
// 获取所有声明了的属性(包括私有属性)
// getFields()仅获取所有public属性
Field[] fields = carClass.getDeclaredFields();
for (Field f : fields) {
System.out.println("Attribute Name:" + f.getName() + " Type:" + f.getType().getSimpleName() + " Modifier:" + modifiers_to_String(f.getModifiers()));
} // Attribute Name:brand Type:String Modifier:private
// 为属性设置值
Car car = (Car) carClass.getDeclaredConstructor().newInstance();
for (Field f : fields) {
if (Modifier.isPrivate(f.getModifiers())) f.setAccessible(true);
if (f.getName().equals("brand")) f.set(car, "BWM");
if (f.getName().equals("color")) f.set(car, "white");
if (f.getName().equals("price")) f.set(car, 500000);
}
System.out.println(car);
}
4. 获取方法
@Test
public void test04() throws Exception {
Class<?> carClass = Car.class;
Car car = (Car) carClass.getDeclaredConstructor().newInstance();
// 获取所有public method(包括所有public的内置方法:如equals,hashCode...)
Method[] methods_public = carClass.getMethods();
for (Method m : methods_public) {
System.out.println("Method Name:" + m.getName() + " Return Type:" + m.getReturnType().getSimpleName() + " Modifier:" + modifiers_to_String(m.getModifiers()) + " params:" + Arrays.toString(paramsClass_to_String(m.getParameterTypes())));
} // Method Name:toString Return Type:String Modifier:public params:[]
System.out.println("=============================================");
// 执行 public String toString()
for (Method m : methods_public) {
if (m.getName().equals("toString")) {
System.out.println((String) m.invoke(car));
}
}
System.out.println("=============================================");
// 获取所有显式声明了的method(包括private方法,不包含隐式的内置方法)
Method[] methods_all = carClass.getDeclaredMethods();
for (Method m : methods_all) {
System.out.println("Method Name:" + m.getName() + " Return Type:" + m.getReturnType().getSimpleName() + " Modifier:" + modifiers_to_String(m.getModifiers()) + " params:" + Arrays.toString(paramsClass_to_String(m.getParameterTypes())));
} // Method Name:run Return Type:void Modifier:private params:[]
System.out.println("=============================================");
// 执行 private void run()
for (Method m : methods_all) {
if (m.getName().equals("run")) {
m.setAccessible(true);
m.invoke(car);
}
}
}
5. Util
private String modifiers_to_String(int modifiers) {
if (Modifier.isPublic(modifiers)) return "public";
if (Modifier.isPrivate(modifiers)) return "private";
if (Modifier.isProtected(modifiers)) return "protected";
return "";
}
private String[] paramsClass_to_String(Class<?>[] paramsClass) {
String[] types = new String[paramsClass.length];
for (int i = 0; i < paramsClass.length; i++) {
types[i] = paramsClass[i].getSimpleName();
}
return types;
}