跳至主要內容

反射

Yang大约 4 分钟JavaJava基础

反射(Reflect)

是在 运行时 动态访问类与对象的技术

  • 在 JDK1.2 版本后的高级特性,隶属于 java.lang.reflect
  • 创建对象的实际从编译的时候延迟到程序运行时
  • 大多数 Java 框架都基于反射实现参数配置、动态注入等特性
// 示例
package com.imooc.reflect;

import com.imooc.reflect.entity.Employee;

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

核心类

Class

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

Constructor

描述
  • 是对 Java 类中的构造方法的抽象
  • 包含了具体类的某个具体构造方法的声明
  • 通过 Constructor 对象调用带参构造方法创建对象
方法
方法用途
classObj.getConstructor()获取指定 public 修饰的构造方法对象
constructorObj.newInstance()通过对应的构造方法创建对象
// 示例
package com.imooc.reflect;

import com.imooc.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.imooc.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,"研发部"
            });
            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()获取指定 public 修饰的方法对象
constructorObj.invoke()调用指定对象的对应方法
package com.imooc.reflect;

import com.imooc.reflect.entity.Employee;

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

/**
 * 利用Method方法类调用
 */
public class MethodSample {
    public static void main(String[] args) {
        try {
            Class employeeClass = Class.forName("com.imooc.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

方法
方法用途
classObj.getField()获取指定 public 修饰的成员变量
fieldObj.get()获取某对象指定成员变量
fieldObj.set()为某对象指定成员变量赋值
package com.imooc.reflect;

import com.imooc.reflect.entity.Employee;

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

/**
 * 利用Field对成员变量赋值/取值
 */
public class FieldSample {
    public static void main(String[] args) {
        try {
            Class employeeClass = Class.forName("com.imooc.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");
            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 (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            //没有找到对应成员变量时抛出的异常
            e.printStackTrace();
        }
    }
}

getDeclared

getDeclaredConstructor(s)|Method(s)|Field(s):获取对应对象

  • getConstructor(s)|Method(s)|Field(s) 只能获取 public 对象
  • getDeclared... 访问非作用域内构造方法、方法、成员变量,会抛出异常
package com.imooc.reflect;

import com.imooc.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.imooc.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) {
                    // pubilc修饰
                    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();
        }
    }
}
上次编辑于:
贡献者: sunzhenyang