Java 反射机制实现原理

反射机制概述

  • 反射机制,是在程序运行时动态的加载类并获取其详细信息,从而操作类或类的属性与方法,一般情况下,一个对象的类型都是在编译期确定的,而通过反射调用的对象其类型在编译期是未知的,所以我们可以通过反射机制动态的调用一个未知类型的方法/属性

反射机制的原理

  • 在我们程序运行过程中,Java 编译器会在编译过程中,通过类加载器将编译完成的.class文件加载到JVM内存中,而反射机制便是通过这些.class进行反编译,从而动态的创建与调用对象

反射机制优缺点

  • 优点:可以在运行时动态的获取类的相关信息,这样更加方便我们做一些扩展功能,更加贴切的面向对象思想
  • 缺点:通过反编译创建的对象,会更加消耗一定的系统资源,另外反射机制可以无限制的调用类内部的私有方法,这样便破坏了类的安全机制

反射机制的使用

  • 创建实体类
import lombok.Data;

/**
 * 文件创作者: 流年
 * 文件描述: 测试反射实体类
 * 创建时间: 2021/7/6 10:22
 */
@Data
public class UserEntity {

    private String name;
    private Integer age;

    /**
     * 无参构造函数
     */
    public UserEntity() {
        System.out.println("调用无参构造函数");
    }

    /**
     * 有参构造函数
     *
     * @param name
     * @param age
     */
    public UserEntity(String name, Integer age) {
        this.name = name;
        this.age = age;
        System.out.println("调用有参构造函数");
    }

    private void test(String name,Integer age){
        System.out.println("调用私有方法"+"name:"+name+"age:"+age);
    }
}
  • 使用 类.class 创建对象
import com.liunian.demo.entity.UserEntity;

/**
 * 文件创作者: 流年
 * 文件描述: 反射机制的使用方式(1)
 * 通过 类.class
 * 创建时间: 2021/7/6 16:10
 */
public class Test01 {
    public static void main(String[] args) {
        Class<UserEntity> userEntityClass = UserEntity.class;
        UserEntity userEntity = userEntityClass.newInstance();
    }
}
  • Class.forName(“类的完整路径地址:包名+类名”)
import com.liunian.demo.entity.UserEntity;

/**
 * 文件创作者: 流年
 * 文件描述: 反射机制的使用方式(2)
 * 通过 Class.forName("类的完整路径地址:包名+类名")
 * 创建时间: 2021/7/6 16:17
 */
public class Test02 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class<?> aClass = Class.forName("com.liunian.demo.entity.UserEntity");
        UserEntity o = (UserEntity) aClass.newInstance();
    }
}
  • 通过对象获取.class
import com.liunian.demo.entity.UserEntity;

/**
 * 文件创作者: 流年
 * 文件描述: 反射机制的使用方式(3)
 * 通过对象获取.class
 * 创建时间: 2021/7/6 16:37
 */
public class Test03 {
    public static void main(String[] args) {
        UserEntity userEntity = new UserEntity();
        Class aClass = userEntity.getClass();
    }
}

  • 调用有参构造函数
import com.liunian.demo.entity.UserEntity;

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

/**
 * 文件创作者: 流年
 * 文件描述: 通过反射调用有参构造函数
 * 创建时间: 2021/7/6 16:17
 */
public class Test02 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class<?> aClass = Class.forName("com.liunian.demo.entity.UserEntity");
//        获取类的有参构造函数
        Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(String.class, Integer.class);
        UserEntity userEntity = (UserEntity) declaredConstructor.newInstance("流年", 123123);
        System.out.println(userEntity);
    }
}

在这里插入图片描述

  • 获取属性信息
import java.lang.reflect.Field;

/**
 * 文件创作者: 流年
 * 文件描述: 通过反射获取属性信息
 * 创建时间: 2021/7/6 16:17
 */
public class Test02 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.liunian.demo.entity.UserEntity");
//        获取公有属性
        Field[] fields = aClass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
//        获取公有属性与私有属性
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }

    }
}

在这里插入图片描述

  • 给私有属性赋值
import com.liunian.demo.entity.UserEntity;

import java.lang.reflect.Field;

/**
 * 文件创作者: 流年
 * 文件描述: 通过反射给私有属性赋值
 * 创建时间: 2021/7/6 16:17
 */
public class Test02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException {
        Class<?> aClass = Class.forName("com.liunian.demo.entity.UserEntity");
        UserEntity userEntity = (UserEntity) aClass.newInstance();
//        获取私有属性
        Field name = aClass.getDeclaredField("name");
//        赋予访问权限
        name.setAccessible(true);
//        为属性赋值
        name.set(userEntity,"测试");
        System.out.println(userEntity);
    }
}

在这里插入图片描述

  • 获取方法
import java.lang.reflect.Method;

/**
 * 文件创作者: 流年
 * 文件描述: 通过反射获取方法
 * 创建时间: 2021/7/6 16:17
 */
public class Test02 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.liunian.demo.entity.UserEntity");
        Method[] methods = aClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("-------------------");
        Method[] declaredMethods = aClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
    }
}

在这里插入图片描述

  • 调用私有方法
import com.liunian.demo.entity.UserEntity;

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

/**
 * 文件创作者: 流年
 * 文件描述: 通过反射调用私有方法
 * 创建时间: 2021/7/6 16:17
 */
public class Test02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class<?> aClass = Class.forName("com.liunian.demo.entity.UserEntity");
        UserEntity userEntity = (UserEntity) aClass.newInstance();
//        获取私有方法
        Method test = aClass.getDeclaredMethod("test",String.class,Integer.class);
//        赋予访问权限
        test.setAccessible(true);
//        调用私有方法
        test.invoke(userEntity,"流年",123);
    }
}

在这里插入图片描述

  • 通过反射机制越过泛型检查
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * 文件创作者: 流年
 * 文件描述: 通过反射机制越过泛型检查
 * 创建时间: 2021/7/6 17:29
 */
public class Test04 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("测试");
        Class aClass = arrayList.getClass();
//        获取add方法
        Method add = aClass.getDeclaredMethod("add", Object.class);
//        调用方法并添加非字符串值
        add.invoke(arrayList,1);
        
        System.out.println(arrayList);
    }
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

索悻流年

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

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

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

打赏作者

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

抵扣说明:

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

余额充值