Jdk源码分析

文章40 |   阅读 10727 |   点赞0

来源:https://yumbo.blog.csdn.net/category_10384063.html

反射工具类jdk.internal.reflect.Reflection 源码解读和总结

x33g5p2x  于2021-12-18 转载在 其他  
字(1.6k)|赞(0)|评价(0)|浏览(376)

在读完jdk.internal.reflect.Reflection类源码后,掌握了几个知识点。

第一点、Reflection类的应用场景

今天突发好奇Class.forName(String)方法。因为对于反射已经相当熟悉了,但是对于这个方法一直没有深究下去,好奇心驱使下,就点进去看了一下,发现这行代码很新奇。

这行代码的含义很简单,就是为了获取调用该方法的class
需要注意的是,他会忽略方法代理的栈帧调用忽略java.lang.reflect.Method.invoke()栈帧调用
总的来说也就是下面这个方法。
Class<?> caller = Reflection.getCallerClass();
这个方法本身是一个native方法,通过IDEA按住Ctrl + 鼠标左键点击会发现jdk类库中有很多地方都用到了这个方法。

!!然则这个方法不能被开发者使用,特此还加了@CallerSensitive注解声明

jdk内部: jdbc中的java.sql.DriverManager中就有调用

实际上我觉得这个方法挺有用的,可惜不让用。基本上native方法都不能使用,加了@CallerSensitive注解的更是提醒开发者不可以使用

第二点、对象判空Objects.requireNonNull();

在阅读源码的过程中发现有一行代码Objects.requireNonNull(currentClass);

这个方法是java.util包下的工具类Objects
内部实现很简单

当然本身对象判空很简单,用不用已经写好的方法对开发来说影响不大。

但既然jdk人家提供了,最好是可以用上,同时还能提升自己代码的13格。

第三点、instanceof

在阅读的过程中看到了其中一个方法Reflection.isSubclassOf() 由于这个方法不是一个public方法所以就不多言了。

联想到 instanceof
意思就算说 :instanceof 左边是一个实例对象,相当于是new出来的,而右边则是类(注意是不带.class的类)

示例代码

class A {
}

class B extends A {
}

public class Demo {
    public static void main(String[] args) {
        final A a = new A();
        final B b = new B();
        System.out.println(b instanceof A);// true
        System.out.println(a instanceof B);// false
    }
}
第四点、jdk11新增方法Reflection.areNestMates(),判断两个class是不嵌套类,很可惜也是一个native而且是不能调用的,会报一个安全异常。

自己尝试了一下调用这个类的verifyMemberAccess()
示例代码如下。从运行结果来看这个方法的作用是做访问权限校验的,就是判断两个类之间有没有访问权限。

例如下面的A对象拥有对Integer对象的访问权限
由于这个A是内部类,并且是非public的声明,所以Integer就访问不了A(调用不了A)

public class Demo {
    static class A {
    }

    public static void main(String[] args) throws IllegalAccessException {
        System.out.println(Reflection.verifyMemberAccess(Integer.class, A.class, new A(), 1));// false
        System.out.println(Reflection.verifyMemberAccess(A.class, Integer.class, new A(), 1));// true
    }
}
总结

这次阅读没啥太多收获,就增长了一点知识点,很偏。
总的感觉来看,jdk.*.*包下的类不需要java应用开发者关注,因为这些都是提供给jvm自己用的,是不对外开放使用的。

相关文章