Java 深入理解反射(反射的性能开销以及优化)

反射的定义以及基本使用

反射是 Java 语言中一个相当重要的特性,它允许正在运行的 Java 程序观测,甚至是修改程序的动态行为。表现为如下两点:

  1. 对于任意一个类,都能知道这个类的所有属性和方法
  2. 对于任意一个对象,都能调用它的任意一个属性和方法

反射涉及的 API 分为三类:Class、Member(Field、Method、Constructor)、Array and Enumerated。详细的基本使用可以参考我以前写的文章 反射基础使用,或者翻阅一下 官方文档。

这里只是简单的概括一下,已经熟悉的小伙伴可以跳过啦~~~

Class

获取 Class 的五种方式:

public final class Main {
   

    enum E {
   
        A, B
    }

    public static void main(String[] args) throws Exception {
   

        // 1. Object.getClass()
        Main main = new Main();
        Class<?> clazzMain = main.getClass();

        Class<?> clazzEnum = E.A.getClass();

        String[] strings = new String[20];
        Class<?> clazzStrings = strings.getClass();

        // 2. The .class Syntax
        Class<?> clazzMainSyntax = Main.class;

        Class<?> clazzBoolean = boolean.class;

        Class<?> clazzIntArray = int[][][].class;

        // 3. Class.forName()
        Class<?> clazzMainName = Class.forName("Main");

        Class<?> clazzDoubleArray = Class.forName("[D");
        Class<?> clazzStringArray = Class.forName("[[Ljava.lang.String;");

        // 4. TYPE Field for Primitive Type Wrappers
        Class<?> clazzDouble = Double.TYPE;
        Class<?> clazzVoid = Void.TYPE;

        // 5. Methods that Return Classes
        Class<?> clazzSuperclass = Main.class.getSuperclass();

        Class<?>[] clazzClasses = Main.class.getClasses();

        Class<?>[] clazzDeclaredClasses = Main.class.getDeclaredClasses();

        Class<?> clazzMainEnclose = Main.class.getEnclosingClass();
    }
}

Member

Member 可能有的小伙伴没怎么见过,它只是一个接口,有三个我们最常见的三个实现类:

  1. Field
  2. Method
  3. Constructor

这里多说一点,这三个实现类都有一个相同的父类,AccessibleObject,在访问私有属性时需要设置 setAccessible 关闭访问权限检查,就是出自这个类里面的方法。

由于篇幅限制,下面就只举例 Field 的使用,其他请参考官方文档:

public final class Main<T> {
   

    private String s;
    public static final int AGE = 18;
    public float aFloat = 0f;
    public boolean[][] booleans;
    public List<String> list = new ArrayList<>();
    public T t;

    public static void main(String[] args) throws Exception {
   
        Class<?> clazz = Class.forName("Main");
        Object object = clazz.getConstructor().newInstance();
        for (Field field : clazz.getDeclaredFields()) {
   
            if (Modifier.isPrivate(field.getModifiers())) {
   
                field.setAccessible(true);
            }
            System.out.println(field.getGenericType());
            System.out.println(field.get(object));
            System.out.println(Modifier.toString(field.getModifiers()));
            System.out.println();
        }
    }
}

Arrays and Enumerated Types

这一小节讲的是两种特殊类型:数组和枚举。我是基本上从来没用过…

所以就简单的熟悉一下 API 好了。

Arrays

public final class Main<T> {
   

    public String[] strings = new String[]{
   "Demo", "Text"};

    public static void main(String[] args) throws Exception {
   
        Class<?> clazz = Main.class;
        Object object = clazz.getConstructor().newInstance();
        Field field = clazz.getField("strings");
        if (field.getType().isArray()){
   
            System.out.println(field.getName());
            System.out.println(field.getGenericType());
            String[] stringArray = (String[]) field.get(object);
            for (String s : stringArray) {
   
                System.out.println(s);
            }
        }

        // 创建一维数组
        Object array = Array
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

川峰

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

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

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

打赏作者

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

抵扣说明:

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

余额充值