Java反射常用方法

本文详细介绍了Java反射的五个关键方面:获取字节码文件对象、利用反射获取构造方法、成员变量和方法,以及如何调用这些方法。通过实例展示了如何动态创建对象和执行私有方法。
摘要由CSDN通过智能技术生成

反射

作用

  • 对于任意一个对象,把对象所有的字段名和值,保存到文件中去
  • 利用反射动态的创造对象和运行方法
1. 获取字节码文件对象
方法描述
Class.forName(String)通过类的全限定名字符串获取字节码文件对象。
类字面量直接使用类的字面量获取字节码文件对象。
对象的方式当已经有类的对象时,通过对象的 getClass() 方法获取字节码文件对象。
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        // 最常用的方式
        Class clazz = Class.forName("Student");
        System.out.println(clazz);

        // 一般通过参数传递的方式
        Class clazz2 = Student.class;
        System.out.println(clazz2);
        System.out.println(clazz==clazz);

        // 通过对象的方式,有类的对象时才可以使用
        Student s = new Student();
        Class clazz3 = s.getClass();
        System.out.println(clazz3);

        System.out.println(clazz2==clazz3);
    }
}
2. 利用反射获得构造方法
方法描述
Class.forName(String)通过类的全限定名字符串获取字节码文件对象。
Class.getConstructors()获取公共的构造方法。
Class.getDeclaredConstructors()获取所有构造方法,包括私有的构造方法。
Class.getConstructor(Class...)获取指定参数类型的公共构造方法。
Class.getDeclaredConstructor(Class...)获取指定参数类型的构造方法,包括私有的构造方法。
Constructor.getModifiers()获取构造方法的修饰符。
Constructor.getParameters()获取构造方法的参数。
Constructor.newInstance(Object...)通过构造方法创建类的实例。
Constructor.setAccessible(true)设置私有构造方法可访问。
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;

public class ReflectDemo2 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 1. 获取Class字节码文件对象
        Class clazz = Class.forName("Student");

        // 2. 获取所有的构造方法
        Constructor[] cons = clazz.getConstructors();
        for (Constructor con: cons) {
            System.out.println(con);
        }
        System.out.println("------------");
        // 获取所有的构造方法,包括私有的
        Constructor[] cons2 = clazz.getDeclaredConstructors();
        for (Constructor con: cons2) {
            System.out.println(con);
        }
        System.out.println("------------");
        // 获取指定的构造方法
        Constructor con3 = clazz.getConstructor(String.class);
        System.out.println(con3);
        System.out.println("------------");
        Constructor con4 = clazz.getDeclaredConstructor(int.class);
        System.out.println(con4);
        System.out.println("------------");
        Constructor con5 = clazz.getDeclaredConstructor(String.class, int.class);
        System.out.println(con5);
        System.out.println("------------");
        // 获取构造方法的权限修饰符
        int modifiers = con5.getModifiers();
        System.out.println(modifiers);
        Parameter[] parameters = con5.getParameters();
        for (Parameter parameter: parameters) {
            System.out.println(parameter);
        }

        con5.setAccessible(true); // 设置私有构造方法可访问
        Student stu = (Student) con5.newInstance("张三", 23);
        System.out.println(stu);
    }
}
public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }
    protected Student(int age) {
        this.age = age;
    }

    private Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
3. 利用反射获取成员变量
方法描述
Class.getFields()获取公共的成员变量。
Class.getDeclaredFields()获取所有的成员变量,包括私有的成员变量。
Class.getField(String)获取指定名称的公共成员变量。
Class.getDeclaredField(String)获取指定名称的成员变量,包括私有的成员变量。
Field.getModifiers()获取成员变量的权限修饰符。
Field.get(Object)获取指定对象上此 Field 表示的字段的值。
Field.setAccessible(true)设置私有成员变量可访问。
Field.set(Object, Object)将指定对象参数上此 Field 表示的字段设置为指定的新值。
import java.lang.reflect.Field;

public class ReflectDemo3 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        // 利用反射获取成员变量
        Class clazz = Class.forName("Student");
        // 获取所有的成员变量
        Field[] fields = clazz.getFields();
        for (Field field: fields) {
            System.out.println(field);
        }
        System.out.printf("------------\n");
        // 获取所有的成员变量,包括私有的
        Field[] fields2 = clazz.getDeclaredFields();
        for (Field field: fields2) {
            System.out.println(field);
        }
        System.out.printf("------------\n");
        // 获取指定的成员变量
        Field field3 = clazz.getField("gender");
        // 获取私有的成员变量
        Field name = clazz.getDeclaredField("name");
        System.out.println(field3);
        System.out.println(name);
        // 获取权限修饰符
        int modifiers = field3.getModifiers();
        int modifiers2 = name.getModifiers();
        System.out.println(modifiers);
        System.out.println(modifiers2);

        System.out.println("------------");

        // 获取成员变量的值
        Student s = new Student("张三", 23);
        name.setAccessible(true); // 设置私有成员变量可访问
        Object value = name.get(s);
        System.out.println(value);

        // 修改对象记录的值
        name.set(s, "李四");
        System.out.println(s);
    }
}
public class Student {
    private String name;
    private int age;
    public String gender;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }
    protected Student(int age) {
        this.age = age;
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
4. 获取成员方法
方法名说明
Method[] getMethods()返回所有成员方法对象的数组(只能拿public的)
Method[] getDeclaredMethods()返回所有成员方法对象的数组,存在就能拿到
Method getMethod(String name, Class<?>… parameterTypes)返回单个成员方法对象(只能拿public的)
Method getDeclaredMethod(String name, Class<?>… parameterTypes)返回单个成员方法对象,存在就能拿到
import java.lang.reflect.Method;

public class ReflectMethodExample {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        // 获取Class对象
        Class<?> clazz = Class.forName("MyClass");

        // 获取所有公共成员方法
        Method[] methods = clazz.getMethods();
        System.out.println("公共成员方法:");
        for (Method method : methods) {
            System.out.println(method);
        }

        System.out.println("-------------");

        // 获取所有成员方法,包括私有的
        Method[] declaredMethods = clazz.getDeclaredMethods();
        System.out.println("所有成员方法:");
        for (Method method : declaredMethods) {
            System.out.println(method);
        }

        System.out.println("-------------");

        // 获取指定的公共成员方法
        Method publicMethod = clazz.getMethod("publicMethod");
        System.out.println("指定的公共成员方法:");
        System.out.println(publicMethod);

        System.out.println("-------------");

        // 获取指定的成员方法,包括私有的
        Method privateMethod = clazz.getDeclaredMethod("privateMethod");
        System.out.println("指定的成员方法:");
        System.out.println(privateMethod);
    }
}

class MyClass {
    public void publicMethod() {
        System.out.println("This is a public method.");
    }

    private void privateMethod() {
        System.out.println("This is a private method.");
    }
}
5. 调用成员方法
Object invoke(Object obj, Object... args) 

实例

public class Main {
    public static void main(String[] args) {
        // 创建一个Calculator对象
        Calculator calculator = new Calculator();

        // 调用invoke方法,传递calculator对象和加法函数,以及所需的参数
        Object result = invoke(calculator, 5, 3);
        
        // 输出结果
        System.out.println("Result of addition: " + result);
    }

    // invoke方法的实现
    public static Object invoke(Object obj, Object... args) {
        try {
            // 获取obj的Class对象
            Class<?> clazz = obj.getClass();
            
            // 获取名为"add"的方法
            java.lang.reflect.Method method = clazz.getMethod("add", int.class, int.class);
            
            // 调用该方法,并传递参数args
            return method.invoke(obj, args);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

// Calculator类
class Calculator {
    // 加法方法
    public int add(int a, int b) {
        return a + b;
    }
}
  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值