详解自定义String类为什么不会被加载,自定义java.lang包下的类会报错

提到这个问题就不得不说一下类加载器和双亲委派机制。

类加载器:
    从Java虚拟机的角度来看,只存在两种不同的类加载器:一种是启动类加载器,一种是继承抽象类java.lang.ClassLoader的。

  1. 启动类加载器(引导类加载器)Bootstrap ClassLoader:
        由C/C++语言实现,该类加载器用于加载Java的核心库,用于提供JVM自身需要的类(加载包名为java、javax、sun等开头的)。
        并不继承java.lana.ClassLoader,没有父加载器。为扩展类加载器和应用程序类加载器的父类加载器(这里的父类不指继承,请不要混淆)。

  2. 扩展类加载器Extension ClassLoader:
        由Java语言编写,派生于ClassLoader类,父类加载器为启动类加载器(再次强调,此处的父类不指继承)。从java.ext.dirs系统属性所指定的目录中加载类库,或从JDK的安装目录的jre/lib/ext子目录(扩展目录)下加载类库。如果用户创建发JAR放在此目录下,也会自动由扩展类加载器加载。

  3. 应用程序类加载器(系统类加载器)Application ClassLoader:
        由Java语言编写,派生于ClassLoader类,父类加载器为启动类加载器。它负责加载环境变量classpath或系统属性java.class.path指定路径下的类库。

双亲委派机制:
    如果一个类加载器收到了类加载的请求,它不会自己加载,而是向上委托,让父类加载器去加载,每一层都如此,直到达到顶层。只有当父类加载器反馈自己无法完成加载请求,子类加载器才会尝试自己去加载,如果子类也加载不到,将报ClassNotFoundException异常。
详解自定义String类为什么不会被加载,自定义java.lang包下的类会报错
到此,回归正题,为什么自定义的String不会被加载?
    当自己定义了一个String类,且包名也是java.lang,为什么不会被加载,因为双亲委派机制,当加载String类时,会一层一层的往上委托,直到在启动类加载器Bootstrap ClassLoader,而启动类加载器能够加载String类,因为在java包下有,所以加载的是Java中的String,而不是自定义的。
    同理为什么自定义java.lang包下的类会报java.lang.SecurityException: Prohibited package name: java.lang,因为java包该由启动类加载器加载,但在该包下没有这个类,那就可能是有恶意行为,所以报出安全异常。
详解自定义String类为什么不会被加载,自定义java.lang包下的类会报错
注:实际工作中,不建议把包名写的跟核心库一样。

谢谢观看。