Java 反射练习

        获取字节码文件对象

package reflectExercise;

/**
 * 反射练习
 *
 */
public class GetClass {
    public static void main(String[] args) throws ClassNotFoundException {
        // 反射 Reflect
        // 在运行状态中,对于任何一个类,都可以知道这个类的所有属性和方法;对于任何一个对象,都能够调用其任意属性和方法
        // 这种动态获取信息及调用对象方法的功能就是反射

        // 利用反射创建的对象可以无视访问权限修饰符调用类中的内容
        // 反射可以和配置文件结合使用,将要创建的对象信息和方法写在配置文件中,配置文件读取到什么类,就创建什么类
        // 读取到什么方法,就调用什么方法
        // 若需求变更时,就无需修改代码,直接修改配置文件即可



        // 反射都是从class字节码文件中获取内容,所以说想要使用反射,必须先获取class字节码

        // 获取字节码文件对象
        // 1.使用Class类中的静态方法:Class.forName(“全类名(包名 + 类名)”)
        Class studentClazz1 = Class.forName("reflectExercise.Student");
        System.out.println(studentClazz1);

        // 2.使用类中的class属性获取
        Class studentClazz2 = Student.class;
        System.out.println(studentClazz2);

        // 3.通过实例对象获取字节码文件对象
        Student student = new Student("张三", 18);
        Class studentClazz3 = student.getClass();
        System.out.println(studentClazz3);

        // 通过三种方式获得的字节码文件对象是同一个
        System.out.println(studentClazz1 == studentClazz2); // true
        System.out.println(studentClazz2 == studentClazz3); // true

    }

}

class Student{
    private String name;
    private int 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;
    }
}

        反射获取构造方法

package reflectExercise;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * 获取构造方法
 */
public class ConstructorExercise {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 通过反射获取类中的构造方法
        // 方法构成规则
        // get 表示获取
        // Declared 表示私有
        // Constructor 构造方法
        // s 表示获取所有(复数形式)
        // get...方法会返回一个指定的Constructor对象,根据构造方法的参数类型(也需要字节码文件)指定
        // get...s方法会返回一个Constructor[]数组,包含当前方法能够获得的所有构造方法

        // 注:若获取到的构造方法是私有的,必须要临时修改其访问权限,否则无法使用

        // 想要通过反射获取,必须先获取其字节码文件对象
        Class clazz = Class.forName("reflectExercise.Person");

        // 获取指定的构造方法
        // 空参
        Constructor constructor1 = clazz.getConstructor();
        // 指定参数 是根据构造方法的参数类型进行查询的,传递的参数需要使用字节码文件对象
        Constructor constructor2 = clazz.getConstructor(String.class, int.class);
        // 使用get方法,不带Declared,无法获得非Public的构造方法
        // Constructor constructor3 = clazz.getConstructor(String.class); // NoSuchMethodException
        Constructor constructor3 = clazz.getDeclaredConstructor(String.class);
        // 非private构造方法,可以直接使用(要根据获得的对应的构造方法传递参数)
        Person p1 = (Person)constructor1.newInstance();
        Person p2 = (Person)constructor2.newInstance("张三", 18);
        System.out.println(p1);
        System.out.println(p2);
        // private构造方法,虽然可以通过Declared方法获取,但是无法直接使用
        // Person p3 = (Person)constructor3.newInstance("张三"); // IllegalAccessException
        // 需要临时修改其访问权限(暴力反射)
        constructor3.setAccessible(true);
        Person p3 = (Person)constructor3.newInstance("张三");
        System.out.println(p3);
        // 使用get...s方法获取
        Constructor[] constructors = clazz.getConstructors();
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
    }
}

class Person{
    private String name;
    private int age;

    public Person() {
    }

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

    private Person(String name) {
        this.name = name;
    }

    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 "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

        反射获取成员变量

package reflectExercise;

import java.lang.reflect.Field;

/**
 * 反射获取成员变量
 *
 */
public class FieldExercise {
    public static void main(String[] args) throws Exception {
        // 获取字节码文件
//        Class clazz = Class.forName("reflectExercise.Animal");
//        // 反射获取成员变量的方法和反射获取构造方法的使用方法一致,不过多赘述
//        Field number = clazz.getField("number");
//        System.out.println(number);
//        // 获取到private的成员变量,仍然无法直接使用
//        Field name = clazz.getDeclaredField("name");
//        System.out.println(name);
//        Field age = clazz.getDeclaredField("age");
//        System.out.println(age);
//
//        Field[] fields = clazz.getDeclaredFields();
//        for (Field field : fields) {
//            System.out.println(field);
//        }


        // 通过反射获取一个类的成员变量并修改
        // void set(Object obj, Object value) 赋值     Object get(Object obj) 获取值
        Animal animal1 = new Animal("狗", 18, "123");
        Animal animal2 = new Animal("猫", 18, "456");
        System.out.println(animal1);
        System.out.println(animal2);
        System.out.println("----------------------------------------");

        // 获取字节码文件对象
        Class clazz = Class.forName("reflectExercise.Animal");
        // 修改姓名
        Field name = clazz.getDeclaredField("name");
        // 对于private权限的变量,临时修改其访问权限
        name.setAccessible(true);
        name.set(animal1, "炫狗");
        name.set(animal2, "哈机密");
        // 修改年龄
        Field age = clazz.getDeclaredField("age");
        age.setAccessible(true);
        age.set(animal1, 1);
        age.set(animal2, 2);
        // 修改编号
        Field number = clazz.getDeclaredField("number");
        number.set(animal1, "147");
        number.set(animal2, "258");

        System.out.println(animal1);
        System.out.println(animal2);


    }

}

class Animal{
    private String name;
    private int age;
    public String number;

    public Animal() {
    }

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

    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 "Animal{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", number='" + number + '\'' +
                '}';
    }
}


        反射获取成员方法

package reflectExercise;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 反射获取成员方法
 * invoke v.调用、实行
 */
public class MethodExercise {
    public static void main(String[] args) throws Exception {
        // 综合,通过反射完成一个对象创建,赋值,使用
        Class clazz = Class.forName("reflectExercise.Car");
        // 获取构造方法
        Constructor constructor1 = clazz.getConstructor();
        Car car1 = (Car)constructor1.newInstance();
        // 获取成员变量
        Field name = clazz.getDeclaredField("name");
        name.setAccessible(true);
        name.set(car1, "benz");
        Field price = clazz.getDeclaredField("price");
        price.setAccessible(true);
        price.set(car1, "123456");
        System.out.println(car1);
        // 获取方法
        Method run = clazz.getMethod("run");
        run.invoke(car1);
        System.out.println("--------------------------------------------");

        // 通过set方法设置对象属性
        Car car2 = (Car)constructor1.newInstance();
        Method setName = clazz.getMethod("setName", String.class);
        setName.invoke(car2, "bmw");
        Method setPrice = clazz.getMethod("setPrice", String.class);
        setPrice.invoke(car2, "456789");
        // get方法得到对象属性
        Method getName = clazz.getMethod("getName");
        Method getPrice = clazz.getMethod("getPrice");
        System.out.println((String) getName.invoke(car2));
        System.out.println((String) getPrice.invoke(car2));
        System.out.println(car2);
        run.invoke(car2);
    }
}

class Car{
    private String name;
    private String price;

    public Car() {}

    public Car(String name, String price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                ", price='" + price + '\'' +
                '}';
    }

    public void run() {
        System.out.println(this.name + "   害虫!!!");
    }
}

 

 

 

上一篇:STM32 | ESP8266 服务器与客户端


下一篇:跨平台WPF框架Avalonia教程 二