Java反射

目录

1.什么是反射

2. 获取class对象的三种方式

3.利用反射获取构造方法

4.利用反射获取成员变量

5.利用反射获取成员方法

6.反射的作用


1.什么是反射

反射允许对成员变量,成员方法和构造方法的信息进行编程访问

2. 获取class对象的三种方式

  1. Class.forName("全类名");
  2. 类名.class
  3. 对象.getclass();

例如:

package yj.com.easthome2.day0910;

/**
 * Class.forName("全类名");
 * 类名.class
 * 对象.getclass();
 */
public class MyReflectDemo01 {
    public static void main(String[] args) throws ClassNotFoundException {
        // Class.forName("全类名");
        //最常用
        Class<?> aClass = Class.forName("yj.com.easthome2.day0910.Student");
        System.out.println(aClass);//class yj.com.easthome2.day0910.Student

        //类名.class
        //更多作为参数传递
        Class<Student> studentClass = Student.class;
        System.out.println(studentClass);//class yj.com.easthome2.day0910.Student

        //对象.getclass();
        //我们已经有了这个类的对象时使用
        Student student = new Student();
        Class<? extends Student> aClass1 = student.getClass();
        System.out.println(aClass1);//class yj.com.easthome2.day0910.Student
    }
}

class Student {
    private String name;
    private int age;

    public Student() {
    }

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

3.利用反射获取构造方法

Class类中用于获取构造方法的方法

  1. Constructor<?>[] getConstructors(): 返回所有公共构造方法对象的数组
  2. Constructor<?>[] getDeclaredConstructors(): 返回所有构造方法对象的数组
  3. Constructor<T>getConstructor(Class<?>... parameterTypes): 返回单个公共构造方法对象
  4. Constructor<T>getDeclaredConstructor(Class<?>... parameterTypes):返回单个构造方法对象

Constructor类中用于创建对象的方法

  1. T newInstance(Object...initargs): 根据指定的构造方法创建对象
  2. setAccessible(boolean flag): 设置为true,表示取消访问检查

例如:

package yj.com.easthome2.day0910.MyReflectDemo02;

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

/**
 * Class类中用于获取构造方法的方法
 *  Constructor<?>[]getConstructors(): 返回所有公共构造方法对象的数组
 *  Constructor<?>[] getDeclaredConstructors(): 返回所有构造方法对象的数组
 *  Constructor<T>getConstructor(Class<?>... parameterTypes): 返回单个公共构造方法对象
 *  Constructor<T>getDeclaredConstructor(Class<?>... parameterTypes):返回单个构造方法对象
 *
 * Constructor类中用于创建对象的方法
 *  T newInstance(Object...initargs): 根据指定的构造方法创建对象
 *  setAccessible(boolean flag): 设置为true,表示取消访问检查
 */
public class MyReflectDemo02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //1.获取class字节码文件对象
        Class<?> aClass = Class.forName("yj.com.easthome2.day0910.MyReflectDemo02.Student");
        //2.获取所有公共构造方法们
        Constructor<?>[] cons = aClass.getConstructors();
        for (Constructor<?> constructor : cons) {
            System.out.println(constructor);
            // 结果:
            //public yj.com.easthome2.day0910.MyReflectDemo02.Student(java.lang.String)
            // public yj.com.easthome2.day0910.MyReflectDemo02.Student()
        }

        System.out.println("----------------");
        //3.获取所有构造方法
        Constructor<?>[] dcs = aClass.getDeclaredConstructors();
        for (Constructor<?> dc : dcs) {
            System.out.println(dc);
            // 结果:
            //private yj.com.easthome2.day0910.MyReflectDemo02.Student(java.lang.String,int)
            // protected yj.com.easthome2.day0910.MyReflectDemo02.Student(int)
            // public yj.com.easthome2.day0910.MyReflectDemo02.Student(java.lang.String)
            // public yj.com.easthome2.day0910.MyReflectDemo02.Student()
        }

        System.out.println("-----------------");
        //4.获取单个公共构造方法
        Constructor<?> con = aClass.getDeclaredConstructor();
        System.out.println(con);
        //结果
        // public yj.com.easthome2.day0910.MyReflectDemo02.Student()

        Constructor<?> con2 = aClass.getDeclaredConstructor(String.class);
        System.out.println(con2);
        //结果
        //public yj.com.easthome2.day0910.MyReflectDemo02.Student(java.lang.String)

        Constructor<?> con3 = aClass.getDeclaredConstructor(int.class);
        System.out.println(con3);
        // protected yj.com.easthome2.day0910.MyReflectDemo02.Student(int)

        Constructor<?> con4 = aClass.getDeclaredConstructor(String.class, int.class);
        System.out.println(con4);
        //private yj.com.easthome2.day0910.MyReflectDemo02.Student(java.lang.String,int)

        System.out.println("------------");
        int modifiers = con4.getModifiers();// 返回此类或接口的Java语言修饰符,以整数编码。
        System.out.println(modifiers);//2

        Parameter[] parameters = con4.getParameters();//获取这个构造方法所有的参数
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
            // java.lang.String arg0
            // int arg
        }

        System.out.println("------------------------");
        //暴力反射
        con4.setAccessible(true);//临时取消权限的校验
        Object nn = con4.newInstance("念念", 10);
        System.out.println(nn);//Student{name='念念', age=10}
    }
}
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 +
                '}';
    }
}

4.利用反射获取成员变量

Class类中用于获取成员变量的方法

  1. Field[] getFields():返回所有公共成员变量对象的数组
  2. Field[] getDeclaredFields():返回所有成员变量对象的数组
  3. Field getField(String name):返回单个公共成员变量对象
  4. Field getDeclaredField(String name):返回单个成员变量对象

Field类中用于创建对象的方法

  1. void set(Object obj, Object value): 赋值
  2. Object get(Object obj) 获取值。

例如:

package yj.com.easthome2.day0910.MyReflectDemo03;

import java.lang.reflect.Field;

/**
 * Class类中用于获取成员变量的方法
 *  Field[] getFields():返回所有公共成员变量对象的数组
 *  Field[] getDeclaredFields():返回所有成员变量对象的数组
 *  Field getField(String name):返回单个公共成员变量对象
 *  Field getDeclaredField(String name):返回单个成员变量对象
 *
 * Field类中用于创建对象的方法
 *  void set(Object obj, Object value): 赋值
 *  Object get(Object obj) 获取值。
 */
public class MyReflectDemo03 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        //1.获取class字节码文件对象
        Class<?> aClass = Class.forName("yj.com.easthome2.day0910.MyReflectDemo03.Student");
        //2.获取成员变量
        Field[] fields = aClass.getFields();
        for (Field field : fields) {
            System.out.println(field);
            //public java.lang.String yj.com.easthome2.day0910.MyReflectDemo03.Student.gender
        }

        System.out.println("----------------");
        //获取所有成员变量,包括私有
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
            // private java.lang.String yj.com.easthome2.day0910.MyReflectDemo03.Student.name
            // private int yj.com.easthome2.day0910.MyReflectDemo03.Student.age
            // public java.lang.String yj.com.easthome2.day0910.MyReflectDemo03.Student.gender
        }

        System.out.println("--------------");
        //获取单个成员变量
        Field field = aClass.getField("gender");
        System.out.println(field);
        // public java.lang.String yj.com.easthome2.day0910.MyReflectDemo03.Student.gender

        //获取单个成员变量(私有)
        Field name = aClass.getDeclaredField("name");
        System.out.println(name);
        //private java.lang.String yj.com.easthome2.day0910.MyReflectDemo03.Student.name

        System.out.println("------------------");
        //获取权限修饰符
        int modifiers = name.getModifiers();
        System.out.println(modifiers);//2

        String name1 = name.getName();//获取成员变量名
        System.out.println(name1);//name
        Class<?> type = name.getType();//获取数据类型
        System.out.println(type);//class java.lang.String

        //获取成员变量记录的值
        Student student = new Student("nn", 10, "男");
        name.setAccessible(true);
        Object o = name.get(student);
        System.out.println(o);//nn

        //修改对象里面记录的值
        name.set(student, "bb");
        System.out.println(student);
        // Student{name='bb', age=10, gender='男'}

    }
}

class Student {
    private String name;
    private int age;
    public String gender;

    public Student() {
    }

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

    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 getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}

5.利用反射获取成员方法

Class类中用于获取成员方法的方法

  1. Method[] getMethods(): 返回所有公共成员方法对象的数组,包括继承的
  2. Method[] getDeclaredMethods(): 返回所有成员方法对象的数组,不包括继承的
  3. Method getMethod(String name, Class<?>... parameterTypes): 返回单个公共成员方法对象
  4. Method getDeclaredMethod(String name, Class<?>... parameterTypes): 返回单个成员方法对象

Method类中用于创建对象的方法

  1. Object invoke(Object obj,Object... args): 运行方法
    1. 参数一:用obj对象调用该方法
    2. 参数二:调用方法的传递的参数(如果没有就不写)
    3. 返回值:方法的返回值(如果没有就不写)

例如:

package yj.com.easthome2.day0910.MyReflectDemo04;

import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * Class类中用于获取成员方法的方法
 *  Method[] getMethods(): 返回所有公共成员方法对象的数组,包括继承的
 *  Method[] getDeclaredMethods(): 返回所有成员方法对象的数组,不包括继承的
 *  Method getMethod(String name, Class<?>... parameterTypes): 返回单个公共成员方法对象
 *  Method getDeclaredMethod(String name, Class<?>... parameterTypes): 返回单个成员方法对象
 *
 * Method类中用于创建对象的方法
 *  Object invoke(Object obj,Object... args): 运行方法
 *  参数一:用obj对象调用该方法
 *  参数二:调用方法的传递的参数(如果没有就不写)
 *  返回值:方法的返回值(如果没有就不写)
 */
public class MyReflectDemo04 {
    public static void main(String[] args) throws Exception {
        //1.获取class字节码文件对象
        Class<?> aClass = Class.forName("yj.com.easthome2.day0910.MyReflectDemo04.Student");
        // Method[] getMethods(): 返回所有公共成员方法对象的数组,包括继承的
        Method[] methods = aClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
            //public java.lang.String yj.com.easthome2.day0910.MyReflectDemo04.Student.toString()
            // public java.lang.String yj.com.easthome2.day0910.MyReflectDemo04.Student.getName()
            // public void yj.com.easthome2.day0910.MyReflectDemo04.Student.setName(java.lang.String)
            // public void yj.com.easthome2.day0910.MyReflectDemo04.Student.sleep()
            // public int yj.com.easthome2.day0910.MyReflectDemo04.Student.getAge()
            // public void yj.com.easthome2.day0910.MyReflectDemo04.Student.setAge(int)
            // public final void java.lang.Object.wait() throws java.lang.InterruptedException
            // public final void java.lang.Object.wait(long,int) 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()
        }

        System.out.println("------------------------");
        //Method[] getDeclaredMethods(): 返回所有成员方法对象的数组,不包括继承的
        Method[] declaredMethods = aClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
            //public java.lang.String yj.com.easthome2.day0910.MyReflectDemo04.Student.toString()
            // public java.lang.String yj.com.easthome2.day0910.MyReflectDemo04.Student.getName()
            // public void yj.com.easthome2.day0910.MyReflectDemo04.Student.setName(java.lang.String)
            // public void yj.com.easthome2.day0910.MyReflectDemo04.Student.sleep()
            // public int yj.com.easthome2.day0910.MyReflectDemo04.Student.getAge()
            // public void yj.com.easthome2.day0910.MyReflectDemo04.Student.setAge(int)
            // private void yj.com.easthome2.day0910.MyReflectDemo04.Student.eat(java.lang.String)
        }

        System.out.println("----------------------");
        //Method getMethod(String name, Class<?>... parameterTypes): 返回单个公共成员方法对象
        Method m = aClass.getMethod("sleep", null);
        System.out.println(m);
        //public void yj.com.easthome2.day0910.MyReflectDemo04.Student.sleep()

        System.out.println("-----------------------------");
        // Method getDeclaredMethod(String name, Class<?>... parameterTypes): 返回单个成员方法对象
        Method method = aClass.getDeclaredMethod("eat", String.class);
        System.out.println(method);
        //private void yj.com.easthome2.day0910.MyReflectDemo04.Student.eat(java.lang.String)

        System.out.println("---------------------");
        //获取方法的修饰符
        int modifiers = method.getModifiers();
        System.out.println(modifiers);//2
        //获取方法的名字
        String name = method.getName();
        System.out.println(name);//eat
        //获取方法的形参
        Parameter[] parameters = method.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
            //java.lang.String arg0
        }
        System.out.println("-------------");
        //获取方法的抛出异常
        Class<?>[] exceptionTypes = method.getExceptionTypes();
        for (Class<?> exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
            //class java.io.IOException
            // class java.lang.NoSuchFieldException
        }

        System.out.println("-----------------------------------");
        //获取方法的返回值
        Student student = new Student();
        //参数一:student表示方法的调用者
        //参数二:"红烧肉"表示在调用方法的时候传递的实际参数
        method.setAccessible(true);
        Object o = method.invoke(student, "红烧肉");//再吃红烧肉
        System.out.println(o);//好吃!
    }
}

class Student {
    private String name;
    private int age;

    public Student() {
    }

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

    public void sleep() {
        System.out.println("睡觉");
    }

    private String eat(String food) throws IOException, NoSuchFieldException {
        System.out.println("再吃" + food);
        return "好吃!";
    }

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

6.反射的作用

  1. 获取一个类里面所有的信息,获取到了之后,再执行其他的业务逻辑
  2. 结合配置文件,动态的创建对象并调用方法

例如:

package yj.com.easthome2.day0910.MyReflectDemo05;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;

public class MyReflectDemo05 {
    public static void main(String[] args) throws Exception {
        Student s = new Student("nn", 10, '女', 162, "睡觉");
        Teacher t = new Teacher("bb", 2000);
        save(s);
    }

    public static void save(Object obj) throws IllegalAccessException, IOException {
        //1.获取字节码文件的对象
        Class<?> aClass = obj.getClass();

        //创建io流
        BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\easthome\\ideaProjects\\javaSE\\java01\\src\\yj\\com\\easthome2\\day0910\\MyReflectDemo05\\aa.txt"));

        //2.获取所有成员变量
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            //获取成员变量的名字
            String name = field.getName();
            //获取成员变量的值
            Object o = field.get(obj);
            // 写出数据

            bw.write(name + "=" + o);
            bw.newLine();
        }
        bw.close();
    }
}

class Student {
    private String name;
    private int age;
    private char gender;
    private double height;
    private String hobby;

    public Student() {
    }

    public Student(String name, int age, char gender, double height, String hobby) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.height = height;
        this.hobby = hobby;
    }

    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 char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public String getHobby() {
        return hobby;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender=" + gender +
                ", height=" + height +
                ", hobby='" + hobby + '\'' +
                '}';
    }
}

class Teacher {
    private String name;
    private double salary;

    public Teacher() {
    }

    public Teacher(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }

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

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯狂的小鸡仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值