26-自定义系统类加载器源码分析与forName方法底层剖析

自定义系统类加载器源码分析与forName方法底层剖析

java.lang.Class
public static Class<?> forName(@NonNls String name,
                            boolean initialize,
                            ClassLoader loader)
                    throws ClassNotFoundException

​ Returns the Class object associated with the class or interface with the given string name, using the given class loader. Given the fully qualified name for a class or interface (in the same format returned by getName) this method attempts to locate, load, and link the class or interface. The specified class loader is used to load the class or interface. If the parameter loader is null, the class is loaded through the bootstrap class loader. The class is initialized only if the initialize parameter is true and if it has not been initialized earlier.

​ 使用给定的类加载器返回与具有给定字符串名称的类或接口关联的类对象。给定类或接口的完全限定名(使用getName返回的相同格式),此方法尝试定位、加载和链接类或接口。指定的类加载器用于加载类或接口。如果参数加载器为空,则通过启动(根)类加载器加载类。仅当initialize参数为true且之前未初始化时,类才会初始化。

​ If name denotes a primitive type or void, an attempt will be made to locate a user-defined class in the unnamed package whose name is name. Therefore, this method cannot be used to obtain any of the Class objects representing primitive types or void.

​ 如果name表示原始类型或void,则将尝试在名称为name的未命名包中查找用户定义的类。因此,此方法不能用于获取表示原始类型或void的任何类对象。

​ If name denotes an array class, the component type of the array class is loaded but not initialized.
​ For example, in an instance method the expression:
​ Class.forName(“Foo”)
​ is equivalent to: (上面的表达式,等价于下面的)
​ Class.forName(“Foo”, true, this.getClass().getClassLoader())
​ Note that this method throws errors related to loading, linking or initializing as specified in Sections 12.2, 12.3 and 12.4 of The Java Language Specification. Note that this method does not check whether the requested class is accessible to its caller.

​ 请注意,此方法抛出与加载、链接或初始化相关的错误,如Java语言规范第12.2、12.3和12.4节所述。请注意,此方法不检查请求的类是否可由其调用方访问。

​ If the loader is null, and a security manager is present, and the caller’s class loader is not null, then this method calls the security manager’s checkPermission method with a RuntimePermission(“getClassLoader”) permission to ensure it’s ok to access the bootstrap class loader.

​ 如果加载程序为空,并且存在安全管理器,并且调用方的类加载程序不为空,则此方法使用RuntimePermission(“getClassLoader”)权限调用安全管理器的checkPermission方法,以确保可以访问启动类加载器。

Parameters:
name - fully qualified name of the desired class
initialize - if true the class will be initialized. See Section 12.4 of The Java Language Specification.
loader - class loader from which the class must be loaded
Returns:
class object representing the desired class //表示所需类的类对象

Class.forName方法:

public static Class<?> forName(String name, boolean initialize,
                               ClassLoader loader)
   throws ClassNotFoundException
    {
        Class<?> caller = null;
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            // Reflective call to get caller class is only needed if a security manager
            // is present.  Avoid the overhead of making this call otherwise.
            caller = Reflection.getCallerClass(); //获取调用forName方法的那个Class对象。
            if (sun.misc.VM.isSystemDomainLoader(loader)) { 
            	//ccl:获取调用forName方法的那个Class对象的类加载器
            	ClassLoader ccl = ClassLoader.getClassLoader(caller);
                if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
                    sm.checkPermission( //进行一个安全性检查
                        SecurityConstants.GET_CLASSLOADER_PERMISSION);
                }
            }
        }
        return forName0(name, initialize, loader, caller);//这个方法是一个native方法,查看不了源码!
}
发布了25 篇原创文章 · 获赞 0 · 访问量 1447

猜你喜欢

转载自blog.csdn.net/qq_40574305/article/details/104793558