java能不能自己写一个类叫java.lang.System

能不能自己写个类叫java.lang.System?

网上提供的答案有说可以,通常不可以,但可以采取另类方法达到这个需求

也有博客说不可以的,刚开始学习的时候还比较疑惑,后来完整地学习完了深入理解Java虚拟机后了解了其中的本质。

我的观点是:不可以!!

   

    类加载器可分为两类:一是启动类加载器(Bootstrap ClassLoader),是C++实现的,是JVM的一部分;另一种是其它的类加载器,是Java实现的,独立于JVM,全部都继承自抽象类java.lang.ClassLoader。jdk自带了三种类加载器,分别是启动类加载器(Bootstrap ClassLoader),扩展类加载器(Extension ClassLoader),应用程序类加载器(Application ClassLoader)。后两种加载器是继承自抽象类java.lang.ClassLoader。关于这三种加载器各自的作用这里不做详细说明,有兴趣的可以自己了解下。

类加载器是有层次的

一般是: 自定义类加载器  >> 应用程序类加载器  >> 扩展类加载器  >> 启动类加载器

上面的层次关系被称为双亲委派模型(Parents Delegation Model)。除了最顶层的启动类加载器外,其余的类加载器都有对应的父类加载器。

再简单说下双亲委托机制:如果一个类加载器收到了类加载的请求,它首先不会自己尝试去加载这个类,而是把这个请求委派给父类加载器,每一个层次的类加载器都是加此,因此所有的加载请求最终到达顶层的启动类加载器,只有当父类加载器反馈自己无法完成加载请求时(指它的搜索范围没有找到所需的类),子类加载器才会尝试自己去加载。

道理是这样,要验证才知道真伪:


首先自己定义一个包叫做java.lang,然后在里面定义一个类叫做Object.

然后在里面定义一个方法叫做doSomething()

package java.lang;

public class Object {

 
    public void doSomething() {
        System.out.println("doSomething");
    }

}
然后在另一个包里面使用Object对象:
package com.test;

import java.lang.Object;

public class ObjectTest {

    public static void main(String[] args) {
        Object o = new Object();
        o.doSomething();
    }

}

运行就会报错java.lang.NoSuchMethodError异常

所以双亲委派模型还是有道理的

所以当我们加载自己写的java.lang.Object时,会默认调用Appliation ClassLoader,这是系统提供的类加载器,肯定支持”双亲委派模型”,所以我们的请求会一步步提交到Bootstrap ClassLoader那里,这个类默认加载的类位于$JAVA_HOME/jre/lib下面的rt.jar包,可以找到我们需要的java.lang.Object类,所以加载的自然就不是我们自己写的Object类了.





猜你喜欢

转载自blog.csdn.net/wxy941011/article/details/80602876
今日推荐