欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 宝鼎售后问题提交 | 后台管理


新闻资讯

MENU

软件开发知识

比如A需要 CAD加密 B模块的方法

点击: 次  来源:宝鼎软件 时间:2017-06-01

原文出处: 笨狐狸

在开始Java的类加载路程之前,可以先参考这里相识一些类加载器在Tomcat中的应用。

在最初执行java这个呼吁时,便会挪用 ClassLoader 的 getSystemClassLoader 要领显式可能隐式加载 main 要领地址的类及其所引用的类。getSystemClassLoader 会返回 AppClassLoader,后者是 URLClassLoader 的一个子类。

先有鸡照旧先有蛋?

所以,最初的一个问题是:先有鸡照旧先有蛋?因为 ClassLoader 的整套体系是打包在 jre/lib/rt.jar 中的。只有 rt.jar 先被加载进来,才气够加载此外类;可是 rt.jar 又是被谁加载的呢?自然就是台甫鼎鼎的 BootstrapClassLoader。它就是“鸡”。所以严格来讲,BootStrapClassLoader 并不是整个别系中的一部门(可以用 -Xbootclasspath 指定bootstrap 加载的位置)。

当 rt.jar 被加载进来后,ClassLoader 会挪用 getSystemClassLoader,软件开发,个中最重要的一步就是初始化 Launcher、ExtClassLoader 以及AppClassLoader,别的就是将 ContextClassLoader 设为 AppClassLoader。ExtClassLoader 与 AppClassLoader 都是 URLClassLoader 的子类,软件开发,别离会加载 java.ext.dirs 和 java.class.path 路径下的 jar资源,前者一般指向 jre/lib/ext 下的所有jar,后者就是我们常常念叨的classpath。区分这两个 ClassLoader 的主要目标是,让他们形成层级干系,ExtClassLoader 为 AppClassLoader 的父 ClassLoader,有了层级干系,便可随意利用双亲委托模子了。

ClassLoader extcl;
        try {
            extcl = ExtClassLoader.getExtClassLoader();
        } catch (IOException e) {
            throw new InternalError(
                "Could not create extension class loader");
        }

        // Now create the class loader to use to launch the application
        try {
            loader = AppClassLoader.getAppClassLoader(extcl);
        } catch (IOException e) {
            throw new InternalError(
                "Could not create application class loader");
        }

        // Also set the context class loader for the primordial thread.
        Thread.currentThread().setContextClassLoader(loader);

ClassLoader毕竟干了什么?

接下来一个较量重要的问题是ClassLoader毕竟干了什么?凡是我们只知道它加载了一个类进了jvm,可是详细做了什么呢?

Java设计者把classloader加载一个类的进程分为4步:

  • 第一步,从某个处所获得我们想要的字节码二进制流;
  • 第二步,读入字节码流并转化为Class;
  • 第三步,链接;
  • 第四步,初始化。
  • 个中,第二步一般较量牢靠,因此ClassLoader提供了defineClass来完成这步;

    protected final Class<?> defineClass(String name, byte[] b, int off, int len,
                                             ProtectionDomain protectionDomain)
            throws ClassFormatError
        {
            protectionDomain = preDefineClass(name, protectionDomain);
    
            Class c = null;
            String source = defineClassSourceLocation(protectionDomain);
    
            try {
                c = defineClass1(name, b, off, len, protectionDomain, source);
            } catch (ClassFormatError cfe) {
                c = defineTransformedClass(name, b, off, len, protectionDomain, cfe,
                                           source);
            }
    
            postDefineClass(c, protectionDomain);
            return c;
        }

    而 ClassLoader 提供了另一个要领 findClass 来完成第一步及第二步,即从某个处所读入类的二进制流,然后挪用 defineClass 返回 Class

    protected Class<?> findClass(final String name)
             throws ClassNotFoundException

    ClassLoader提供了resolveClass要领完成第三步链接的事情。

    protected final void resolveClass(Class<?> c)

    除非非凡需要,不然只管重载 findClass 而不是 loadClass。

    loadClass 是 Java 1.0 就存在的类,图纸加密,为了加强可扩展性,将findClass和resolveClass封装到了loadClass中,一般我们只需要界说类的加载路径,因此仅需包围findClass。

    凡是我们显示加载类一般会用到ClassLoader.loadClass、Class.forName,他们的区别见这里。

    resolveClass做了什么?

    resolveClass最终挪用了一个当处所法做link,这里的link主要做了这么几步工作:

    1. 验证Class以确保类装载器名目和行为正确;
    2. 筹备后续步调所需的数据布局;
    3. 理会所引用的其他类。

    关于这些内容的详细细节,请参考这里。

    ClassNotFoundException、NoClassDefFoundError、ClassCastException常见问题

    ClassNotFoundException一般产生在显式类加载;NoClassDefFoundError一般产生在隐式加载;ClassCastException一般产生在jar包斗嘴,好比某个jar包已经被更上层的加载器加载了,但你却要求他强制转为基层加载器加载的同名类;

    链接的相关常识

    接下来讲讲链接的相关常识。

    为什么会发现链接器?

    最劈头伐员写措施都在一个文件里,跟着措施局限的增加,逐渐发明越来越难以维护,扩展。于是,分多个文件和模块就成为一定。