Class.getClasses()方法调用过程

来源:互联网 发布:知乎 日本人写的书 编辑:程序博客网 时间:2024/05/20 04:10
public Class<?>[] getClasses() {
        // be very careful not to change the stack depth of this
        // checkMemberAccess call for security reasons
        // see java.lang.SecurityManager.checkMemberAccess
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);

调用过程:首先是checkMemberAccess:

private void checkMemberAccess(int which, Class<?> caller, boolean checkProxyInterfaces) {

//参数解释:which是代表权限的参数,在Member接口中声明了两个final的int变量:PUBLIC=0,DECLARED=1,这个which就是跟他们在比较

//caller是上一层传入的Class<?>的getcallerclass也就是Reflection中的getcallerclass()方法,用来获得调用者的类
        final SecurityManager s = System.getSecurityManager();  

//getSecurityManager这个方法有如下方法:

//public static SecurityManager getSecurityManager() {   
       // return security;  

//security是java的安全模型之安全管理器,负责访问控制和对外部资源的访问控制,因为类装载器和安全管理器是可以由用户set的,所以这部分先检查这个对象是否为空。

     //}
        if (s != null) { //如果不空的话
            final ClassLoader ccl = ClassLoader.getClassLoader(caller); //拿到被调用类的类加载器
            final ClassLoader cl = getClassLoader0();//这个是一个native本地方法,调用到操作系统相关的技术利用库函数进行完成
            if (!isCheckMemberAccessOverridden(s)) {//检查函数是否有重写的权限
                // Inlined SecurityManager.checkMemberAccess
                if (which != Member.PUBLIC) {//如果调入的which参数(也就是传入的权限值)不等于public(也就是0)
                    if (ccl != cl) {  //如果类加载器不是本地方法利用库函数拿到的类加载器
                        s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION); //验证这个安全管理器是不是具有相应的权限

//SecurityConstants里有一个final常量CHECK_MEMBER_ACCESS_PERMISSION = new RuntimePermission("accessDeclaredMembers"),//RuntimePermission继承自BasicPermission又继承自Permission,这里的用法是一种含参的构造函数,意思是这个RuntimePermission的name
//是accessDeclaredMembers这种权限
                    }
                }
            } else {
                // Don't refactor; otherwise break the stack depth for
                // checkMemberAccess of subclasses of SecurityManager as specified.
                s.checkMemberAccess(this, which);//验证这个安全管理的权限
            }
            this.checkPackageAccess(ccl, checkProxyInterfaces);//验证调用的这个类是由具有包权限(各种权限检查)
        }
    }


在各种权限检查完成之后return了一个匿名内部类        // Privileged so this implementation can look at DECLARED classes,
        // something the caller might not have privilege to do.  The code here
        // is allowed to look at DECLARED classes because (1) it does not hand
        // out anything other than public members and (2) public member access
        // has already been ok'd by the SecurityManager.


        return java.security.AccessController.doPrivileged(  //依旧是各种权限检查,这个doPrivileged是一个本地方法,要求传入一个PrivilegedAction接口的实现类
            new java.security.PrivilegedAction<Class<?>[]>() {
                public Class[] run() {  //PriviledgedAction接口中的唯一一个需要实现类实现的方法就是run()方法
                    List<Class<?>> list = new ArrayList<>(); //构建一个存放class对象的容器List容器
                    Class<?> currentClass = Class.this;//Class.this得到的是调用getClasses()方法的类的Class对象
                    while (currentClass != null) {

                        Class<?>[] members = currentClass.getDeclaredClasses();//getDeclared方法有两个步骤:第一个步骤是 checkMemberAccess还是前面讲过的各种权限检查

//第二个步骤就是调用getDeclaredClasses0()这个是本地方法,所有的native方法都不需要函数体由操作系统自身的技术调用库函数来处理得到

                        for (int i = 0; i < members.length; i++) {
                            if (Modifier.isPublic(members[i].getModifiers())) {  //getModifiers()方法也是native方法,会生成一个int的返回值,Modifier中的isPublic 返回的是PUBLIC(也就//是1)做一个&操作,如果不等于0则为true

                                list.add(members[i]);//将符合isPublic的class加入到list容器中

                            }
                        }
                        currentClass = currentClass.getSuperclass();//getSuperclass()也是一个native方法
                    }
                    return list.toArray(new Class[0]);//这里new Class[0]的意义是将list转换为Array的这个过程中,初始化Array是一个装载Class类型的Array(即Class[] a这种类型的数//组)
                }
            });

    }


0 0