美文网首页
创建一个java.lang.Test类,能被加载吗?

创建一个java.lang.Test类,能被加载吗?

作者: gigglesoso | 来源:发表于2020-07-02 15:45 被阅读0次

java中类加载器有三种:

  • Bootstrap类加载器 负责加载java的核心类包,比如rt.jar
  • 拓展类加载器 负责加载java的拓展类包
  • 应用类加载器 负责加载我们项目classpath下的类
    假如我们自定义了一个java.lang.Test的类,尝试查看哪个类加载器会加载这个类?
    public static void main(String[] args) {
        Test test = new Test();
        ClassLoader classLoader = test.getClass().getClassLoader();
        System.out.println(classLoader);
    }
Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.lang
    at java.lang.ClassLoader.preDefineClass(ClassLoader.java:662)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:761)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at TestClazz.main(TestClazz.java:11)

可见这种自定义的用java开头的包名是不能被类加载器加载的。

问题,那为什么java的核心类包里的类可以被加载呢?java.lang.String怎么就不报异常呢?原因很简单,因为java.lang.String类使用到的类加载器是BootStrap类加载器,不会有这个校验,我们自定义的类java.lang.Test即使要去被加载,也由于处于我们classpath下,最后尝试去加载它的是我们的应用类加载器,而应用类加载器加载类的时候会有下面的一个校验方法

   private ProtectionDomain preDefineClass(String name,ProtectionDomain pd){
        if (!checkName(name))
            throw new NoClassDefFoundError("IllegalName: " + name);
       // 这里会校验类名不能是java.开头的
        if ((name != null) && name.startsWith("java.")) {
            throw new SecurityException
                ("Prohibited package name: " +
                 name.substring(0, name.lastIndexOf('.')));
        }
        if (pd == null) {
            pd = defaultDomain;
        }
        if (name != null) checkCerts(name, pd.getCodeSource());
        return pd;
    }

可见应用类加载器在加载类时候,不能加载java.开头的类,所以尝试加载上述自定义的类会抛出异常。
***************************************分割线************************************
那假如我们定义一个java.lang.String类,会有什么后果呢,这个类是核心类包中已经有的类了。

    public static void main(String[] args) {
        java.lang.String test = new String();
        ClassLoader classLoader = test.getClass().getClassLoader();
        System.out.println(classLoader);
    }

运行结果时null,表名是bootstrap类加载器,并且加载的是核心类包里的String类,并不是自己定义的这个,可见即使自己定义了核心类包里的同名类,最后的结果是类加载器会加载核心类包里的,自己定义的不会被加载。

相关文章

  • 创建一个java.lang.Test类,能被加载吗?

    java中类加载器有三种: Bootstrap类加载器 负责加载java的核心类包,比如rt.jar 拓展类加载...

  • 单例模式 01 小树

    即使 singleton 类被加载 类也不会创建 , 只有在主动调用getInstance后才会触发内部类的加载 ...

  • 类加载过程

    创建类加载过程 将创建对象所属类加载到方法区  如果对应类有父类,将先加载父类  修饰的静态变量随着类的加载进方法...

  • Java对象

    对象创建 类加载 首先jvm会判断这个类是否已经被加载、解析和初始化,如果没有就进行相应的类加载过程 分配空间 分...

  • 反射

    类加载过程的核心:任何一个类被系统使用时候都会将class文件加载进内存并创建一个Class对象,同时会初始化静态...

  • java基础知识之java类加载器

    1. 什么是类加载器 类加载器就是用来加载类的东西!类加载器也是一个类:ClassLoader 类加载器可以被加载...

  • 【深入理解java虚拟机】3. 对象的创建过程

    对象的创建 1. 检查类是否被加载 当jvm执行new 指令时, 会检查 指令的参数是否能再常量池中定位到类的符号...

  • Java类加载机制

    你知道Java的类加载机制吗?字节码文件时如何被加载使用的你?今天我们从以下几个方面,一起聊聊类加载。 类加载过程...

  • Java类加载机制和对象创建过程

    Java类加载机制和对象创建过程 1、类加载 类加载的时机 ​ 类加载,即虚拟机加载.class文件。什么时候虚拟...

  • 06 Java类加载器

    1 类加载器概念 1.1 加载概念 加载指的是将类的 class 文件读入到内存,并为之创建一个 java.lan...

网友评论

      本文标题:创建一个java.lang.Test类,能被加载吗?

      本文链接:https://www.haomeiwen.com/subject/jedrqktx.html