反射Reflect

什么是反射?

  • 反射是运行时动态访问类与对象的技术
  • 反射是JDK1.2版本后的高级特性,隶属于java.lang.reflect

反射的核心类

Class类

  • Class是JVM中代表“类和接口”的类
  • Class对象具体包含了某个特定类的结构信息
  • 通过Class对象可获得对应类的构造方法、方法、成员变量
Class核心方法说明
Class.forName()静态方法,用于获取指定的Class对象
classObj.newInstance()通过默认的构造方法创建新的对象
classObj.getConstructor()获得指定的public修饰构造方法Constructor对象
classObj.getMethod()获得指定的public修饰方法Method对象
classObj.getField()获得指定的public修饰成员变量Field对象

用代码简单的举个例子

  1. 首先创建一个Entity类Employee类
package com.pro.reflect.entity;

/**
 * 员工实体类
 */
public class Employee {

    static {
        //类加载时执行
        System.out.println("Employee类已被加载到JVM,并已初始化");

    }
    private Integer eno;
    public String ename;
    private Float salary;
    private String dname;

    public Employee() {
        System.out.println("Employee默认构造方法已被执行!");

    }

    public Employee(Integer eno, String ename, Float salary, String dname) {
        this.eno = eno;
        this.ename = ename;
        this.salary = salary;
        this.dname = dname;
        System.out.println("Employee带参构造方法已被执行!");
    }


    public Integer getEno() {
        return eno;
    }

    public void setEno(Integer eno) {
        this.eno = eno;
    }

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public Float getSalary() {
        return salary;
    }

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

    public String getDname() {
        return dname;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "eno=" + eno +
                ", ename='" + ename + '\'' +
                ", salary=" + salary +
                ", dname='" + dname + '\'' +
                '}';
    }

    public Employee updateSalary(Float val) {
        this.salary = this.salary + val;
        System.out.println(this.ename + "调薪至" + this.salary + "元");
        return this;
    }
}


  1. ClassSample类
package com.pro.reflect;

import com.pro.reflect.entity.Employee;

public class ClassSample {
    public static void main(String[] args) {
        try {
            //Class.forName()方法将指定的类加载到JVM,并返回对应的Class对象
            Class employeeClass = Class.forName("com.pro.reflect.entity.Employee");
            System.out.println("Employee类已被加载到JVM");
            Employee emp = (Employee) employeeClass.newInstance();//返回Object对象
        } catch (ClassNotFoundException e) {
            //当类名与类路径书写错误时,抛出‘类无法找到’异常
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            //当在作用域外访问对象方法或成员变量时,抛出‘非法访问’异常
            e.printStackTrace();
        } catch (InstantiationException e) {
            //当对象无法被实例化时,抛出‘实例化’异常
            e.printStackTrace();
        }

    }
}

在这里插入图片描述

Constructor构造方法类

  • Constructor类是对Java类中的构造方法的抽象
  • Constructor对象包含了具体类的某个具体构造方法的声明
  • 通过Constructor对象调用带参构造方法创建对象
Constructor类核心方法说明
classObj.getConstructor()获得指定的public修饰构造方法对象
constructorObj.newInstance()通过默认的构造方法创建新的对象
  1. Constructor类
package com.pro.reflect;

import com.pro.reflect.entity.Employee;

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

/**
 * 利用带参构造方法创建对象
 */
public class ConstructorSample {
    public static void main(String[] args) {
        try {
            Class employeeClass = Class.forName("com.pro.reflect.entity.Employee");
            Constructor constructor = employeeClass.getConstructor(new Class[]{
                    Integer.class, String.class, Float.class, String.class
            });//获取指定格式的构造方法,Class数组描述参数的类型
            Employee employee = (Employee) constructor.newInstance(new Object[]{
                    100, "李磊", 3000f, "研发部"
            });//传入Object数组参数值,顺序与参数类型对应
            System.out.println(employee);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            //没有找到与之对应格式的方法
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            //当被调用的方法的内部抛出了异常而没有被捕获时,
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

Method方法类

  • Method对象是对某个类中的方法的描述
  • Method对象使用classObj.getMethod()方法获取
  • 通过Method对象调用指定对象的对应方法
Method核心方法说明
classObj.getMethod()获得指定的public修饰方法对象
methodObj.invoke()调用指定对象的对应方法
  1. MethodSample类
package com.pro.reflect;

import com.pro.reflect.entity.Employee;

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

public class MethodSample {
    public static void main(String[] args) {
        try {
            Class employeeClass = Class.forName("com.pro.reflect.entity.Employee");
            Constructor constructor = employeeClass.getConstructor(new Class[]{
                    Integer.class, String.class, Float.class, String.class
            });
            Employee employee = (Employee) constructor.newInstance(new Object[]{
                    100, "李磊", 3000f, "研发部"
            });
            Method updateSalaryMethod = employeeClass.getMethod("updateSalary", new Class[]{
                    Float.class
            });//方法的名字和参数的类型
            Employee employee1 = (Employee)updateSalaryMethod.invoke(employee, new Object[]{1000f});
            //执行的对象和参数的参数值
            System.out.println(employee1);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

Field成员变量类

  • Field对应某个具体类中的成员变量的声明
  • Field对象使用classObj.getField()方法获取
  • 通过Field对象可为某对象成员变量赋值/取值
Field核心方法说明
classObj.getField()获得指定的public修饰成员变量Field对象
fieldObj.set()为某对象指定成员变量赋值
fieldObj.get()获取某对象指定成员变量数值
  1. FieldSample类
package com.pro.reflect;

import com.pro.reflect.entity.Employee;

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

public class FieldSample {
    public static void main(String[] args) {
        try {
            Class employeeClass = Class.forName("com.pro.reflect.entity.Employee");
            Constructor constructor = employeeClass.getConstructor(new Class[]{
                    Integer.class, String.class, Float.class, String.class
            });
            Employee employee = (Employee)constructor.newInstance(new Object[]{
                    100, "李磊", 3000f, "研发部"
            });
            Field enameField = employeeClass.getField("ename");//注意是public的成员变量
            enameField.set(employee, "李雷");//执行的对象和参数的参数值
            String ename = (String) enameField.get(employee);//读取的对象
            System.out.println("ename:"+ename);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            //没有找到对应成员变量时抛出的异常
            e.printStackTrace();
        }

    }
}

在这里插入图片描述

getDeclared系列方法

  • getDeclaredConstuctor(s)|Method(s)|Field(s)获取对应的对象,s是全部对象
  • getConstuctor(s)|Method(s)|Field(s)只能获取public对象
  • 访问非作用域(私有)内构造方法,方法,成员变量,会抛出异常
package com.pro.reflect;

import com.pro.reflect.entity.Employee;

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

public class getDeclaredSample {
    public static void main(String[] args) {
        try {
            Class employeeClass = Class.forName("com.pro.reflect.entity.Employee");
            Constructor constructor = employeeClass.getConstructor(new Class[]{
                    Integer.class, String.class, Float.class, String.class
            });
            Employee employee = (Employee) constructor.newInstance(new Object[]{
                    100, "李磊", 3000f, "研发部"
            });
            Field[] fields = employeeClass.getDeclaredFields();//获取当前类中的所有成员变量
            for (Field field : fields) {
//                System.out.println(field.getName());
                if(field.getModifiers() == 1){
                    //public 修饰
                    Object val = field.get(employee);
                    System.out.println(field.getName() + ":" + val);
                } else if (field.getModifiers() == 2) {
                    //private 修饰
                    String methodName = "get" + field.getName().substring(0, 1).toUpperCase()
                            + field.getName().substring(1);
                    Method getMethod = employeeClass.getMethod(methodName);
                    Object ret = getMethod.invoke(employee);
                    System.out.println(field.getName() + ":" + ret);
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值