假设我们有一个Car.class(类对象),我们可以通过操作它,即操作字节码文件获取类、属性、方法、实例化对象,那么这个过程叫做java的反射
package com.it.reflect;
public class Car {
//三个属性
private String name;
private int age;
private String color;
//普通方法
private void run(){
System.out.println("私有方法run......");
}
//无参数构造
public Car() {
}
//有参数构造
public Car(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
//对应get、set的方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
//toString方法
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", age=" + age +
", color='" + color + '\'' +
'}';
}
}
TestCar.java
package com.it.reflect;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestCar {
//1.获取class对象多种方式 class对象就是字节码文件
@Test
public void test01() throws Exception {
//1.类名.class
Class clazz1 = Car.class;
//2.对象.getClass()
Class clazz2 = new Car().getClass();
//3.Class.forName("全路径")
Class clazz3 = Class.forName("com.it.reflect.Car");
//实例化
// Car car = (Car) clazz3.getDeclaredConstructor().newInstance();
Car car = (Car) clazz3.getConstructor().newInstance();
System.out.println(car);
}
//2.获取构造方法
@Test
public void test02() throws Exception{
Class clazz = Car.class;
//获取所有构造
//Constructor[] constructors = clazz.getConstructors();//getConstructor只能获取public构造方法
Constructor[] constructors = clazz.getDeclaredConstructors();//getDeclaredConstructor可以获取所有构造方法
for(Constructor c:constructors){
System.out.println("方法名称"+c.getName()+"参数个数:"+c.getParameterCount());
}
//指定有参构造创建对象
//1)构造public
// Constructor c1 =
// clazz.getConstructor(String.class, int.class, String.class);
// Car car1 = (Car) c1.newInstance("benz", 20, "black");
// System.out.println(car1);
//2)构造private
//得到有参构造
Constructor c2 = clazz.getDeclaredConstructor(String.class, int.class, String.class);
//setAccessible(true)方法允许访问私有方法
c2.setAccessible(true);
Car car2 = (Car)c2.newInstance("bwm", 20, "white");
System.out.println(car2);
}
//3.获取属性
@Test
public void test03()throws Exception{
Class clazz = Car.class;
//实例化
Car car = (Car) clazz.getDeclaredConstructor().newInstance();
//获取所有public属性
// Field[] fields = clazz.getFields();
//获取所有属性(包含private属性)
Field[] fields1 = clazz.getDeclaredFields();
for(Field a:fields1 ){
if(a.getName().equals("name")){
//设置允许访问
a.setAccessible(true);
a.set(car,"audi");
}
System.out.println(a.getName());
System.out.println(car);
}
}
//4.获取方法
@Test
public void test04() throws Exception{
Car car = new Car("wow",20,"red");
Class clazz = car.getClass();
//1 public方法 getMethods获取方法
Method[] methods = clazz.getMethods();
for (Method method:methods){
//System.out.println(method.getName());
//执行方法method.invoke()方法
if(method.getName().equals("toString")){
String invoke = (String) method.invoke(car);
//System.out.println("toString方法执行了"+invoke);
}
}
//private方法
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method methods1:
declaredMethods) {
//执行run()私有方法
if(methods1.getName().equals("run")){
methods1.setAccessible(true);
methods1.invoke(car);
}
}
}
}