类加载器“如果我定义了一个类名与Java核心类类名相同,那它还能被加载吗?”

简介: 类加载器“如果我定义了一个类名与Java核心类类名相同,那它还能被加载吗?”



       在Java中,如果你定义了一个类名与Java核心类(比如java.lang.Object)相同的类,按照默认的类加载机制,这个自定义类将不会被加载。这是因为类加载器在加载类的过程中会按照双亲委派模型,优先委派给父类加载器去加载类。

双亲委派模型

       双亲委派模型要求除了顶层的启动类加载器外,其余的类加载器都应有自己的父类加载

器。不过这里类加载器之间的父子关系一般不是以继承( Inheritance )的关系来实现的,而是通常使用组合(Composition )关系来复用父加载器的代码。

       

双亲委派模型的工作过程是:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到最顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去完成加载。

       所以当我们定义一个与系统内置类同名的类时,类加载器的双亲委派模型会使得类加载器首先向上级委派请求加载类,直到达到启动类加载器。如果所有的类加载器都无法加载这个类,那么才会由当前类加载器尝试加载。

       并且Java的核心类是由启动类加载器(Bootstrap Class Loader)加载的,而启动类加载器是用C++实现的,并不是一个普通的Java类加载器。它负责加载核心的Java API,如 java.lang.Object等。当虚拟机遇到与核心类同名的类时,由于双亲委派模型,启动类加载器已经加载了这个核心类,因此不会再委派给应用程序类加载器加载你定义的同名类,从而导致你定义的类不会被加载。

       所以,尽管你可以定义一个类名与Java核心类相同的类,但是在正常情况下,由于双亲委派机制,自定义类不会被加载,而是使用核心类。

那怎么样才能让它加载我这个类呢?

       如果你希望一个类加载器加载你定义的同名类而不使用双亲委派模型,可以考虑以下两种方式:

自定义类加载器

       你可以编写一个自定义的类加载器,重写它的loadClass方法。在这个方法中,你可以控制类的加载逻辑,不再按照双亲委派模型。你可以通过重写loadClass方法,自己定义加载规则,确保你的类被加载。

public class CustomClassLoader extends ClassLoader {
    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        // 自定义加载逻辑,确保加载你的类
        if ("java.lang.Object".equals(name)) {
            return findClass(name);
        }
        return super.loadClass(name);
    }
}
使用线程上下文类加载器

       在一些特殊情况下,你可以使用线程上下文类加载器(Thread Context Class Loader)。线程上下文类加载器是由线程的创建者设定的,它可以独立于双亲委派模型加载类。你可以在代码中通过Thread.currentThread().setContextClassLoader()来设置线程上下文类加载器,使得该线程在加载类时使用你指定的类加载器。

Thread.currentThread().setContextClassLoader(new CustomClassLoader());

       值得注意的是,自定义类加载器需要继承自ClassLoader类,并实现findClass方法来定义类的加载逻辑。使用自定义类加载器需要小心,确保不破坏Java类加载的一些基本规则,以避免出现类加载的冲突和问题。

相关文章
|
15天前
|
Java 编译器
Java重复定义变量详解
这段对话讨论了Java中变量作用域和重复定义的问题。学生提问为何不能重复定义变量导致编译错误,老师通过多个示例解释了编译器如何区分不同作用域内的变量,包括局部变量、成员变量和静态变量,并说明了使用`this`关键字和类名来区分变量的方法。最终,学生理解了编译器在逻辑层面检查变量定义的问题。
Java重复定义变量详解
|
16天前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
39 17
|
9天前
|
Java Maven Spring
Java Web 应用中,资源文件的位置和加载方式
在Java Web应用中,资源文件如配置文件、静态文件等通常放置在特定目录下,如WEB-INF或classes。通过类加载器或Servlet上下文路径可实现资源的加载与访问。正确管理资源位置与加载方式对应用的稳定性和可维护性至关重要。
|
7天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
11天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
51 4
|
12天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
28 2
|
16天前
|
存储 安全 Java
如何保证 Java 类文件的安全性?
Java类文件的安全性可以通过多种方式保障,如使用数字签名验证类文件的完整性和来源,利用安全管理器和安全策略限制类文件的权限,以及通过加密技术保护类文件在传输过程中的安全。
|
20天前
|
Java 数据格式 索引
使用 Java 字节码工具检查类文件完整性的原理是什么
Java字节码工具通过解析和分析类文件的字节码,检查其结构和内容是否符合Java虚拟机规范,确保类文件的完整性和合法性,防止恶意代码或损坏的类文件影响程序运行。
|
20天前
|
Java API Maven
如何使用 Java 字节码工具检查类文件的完整性
本文介绍如何利用Java字节码工具来检测类文件的完整性和有效性,确保类文件未被篡改或损坏,适用于开发和维护阶段的代码质量控制。
|
20天前
|
存储 Java 编译器
java wrapper是什么类
【10月更文挑战第16天】
23 3