已解决java.lang.ClassCircularityError: 类循环依赖错误的正确解决方法,亲测有效!!!

不念不忘少年蓝@ 2024-05-11 09:24 129阅读 0赞

已解决java.lang.ClassCircularityError: 类循环依赖错误的正确解决方法,亲测有效!!!

目录

问题分析

报错原因

解决思路

解决方法

代码重构

类加载器策略调整

总结

博主v:XiaoMing_Java


问题分析

java.lang.ClassCircularityError是在Java类加载过程中,类加载器尝试直接或间接自己加载自己时抛出的错误。这通常发生在类的加载和链接阶段,是一个比较罕见的错误,它指出了类加载器在处理类的加载请求时遇到了循环依赖。

报错原因

类循环依赖错误主要由以下原因引起:

  1. 类A在其静态初始化过程中直接或间接地依赖于自己的加载。
  2. 类A和类B相互依赖,并在彼此的类初始化过程中尝试加载对方。
  3. 在复杂的应用中,类的加载顺序或加载方式导致循环依赖。

解决思路

解决ClassCircularityError的思路主要集中在避免类的循环依赖,重构代码,以及调整类加载器的加载策略:

  1. 分析和理解错误发生的上下文,特别是涉及的类的依赖关系。
  2. 调整类的静态初始化代码,避免在类初始化阶段引用尚未完全加载的类。
  3. 使用不同的类加载器,或调整类加载器的策略。

解决方法

代码重构

重新设计类的依赖关系和初始化策略,以避免循环依赖。

  1. public class ClassA {
  2. private static int A_VALUE = ClassB.getBValue();
  3. public static int getAValue() {
  4. return A_VALUE;
  5. }
  6. }
  7. public class ClassB {
  8. private static int B_VALUE = ClassA.getAValue();
  9. public static int getBValue() {
  10. return B_VALUE;
  11. }
  12. }
  13. // 重构后的示例
  14. public class ClassA {
  15. private static int A_VALUE = 100; // 移除对ClassB的直接依赖
  16. public static int getAValue() {
  17. return A_VALUE;
  18. }
  19. }
  20. public class ClassB {
  21. private static int B_VALUE = 200; // 移除对ClassA的直接依赖
  22. public static int getBValue() {
  23. return B_VALUE;
  24. }
  25. }

类加载器策略调整

修改应用的类加载器策略,确保类的加载顺序和方式不会引起循环依赖。

  1. ClassLoader parentClassLoader = ClassLoader.getSystemClassLoader().getParent();
  2. ClassLoader customClassLoader = new CustomClassLoader(parentClassLoader);
  3. class CustomClassLoader extends ClassLoader {
  4. public CustomClassLoader(ClassLoader parent) {
  5. super(parent);
  6. }
  7. @Override
  8. public Class<?> loadClass(String name) throws ClassNotFoundException {
  9. if (name.startsWith("com.myapp")) {
  10. // 自定义加载策略
  11. return super.loadClass(name, true);
  12. }
  13. return super.loadClass(name);
  14. }
  15. }
  16. // 使用自定义类加载器加载应用
  17. Class<?> classA = customClassLoader.loadClass("com.myapp.ClassA");

总结

java.lang.ClassCircularityError通常是由于类的循环依赖造成的,在处理此错误时,必须仔细分析涉及的类和它们的加载顺序。通过重构代码,移除循环依赖,并可能需要调整类加载器的策略,可以有效解决这一问题。这要求开发者对Java类加载机制和类初始化过程有深入的理解。在设计和实现大型应用时,合理组织类和模块的结构至关重要,以避免此类问题的发生。

以上是此问题报错原因的解决方法,欢迎评论区留言讨论是否能解决,如果本文对你有帮助 欢迎关注**、点赞 、收藏 、评论, 博主才有动力持续记录遇到的问题!!!**

博主v:XiaoMing_Java

?作者简介:嗨,大家好,我是小明(小明Java问道之路),互联网大厂后端研发专家,2022博客之星TOP3 / 博客专家 / CSDN后端内容合伙人、InfoQ(极客时间)签约作者、阿里云签约博主、全网 6 万粉丝博主。


? 文末获取联系 ? ?? 精彩专栏推荐订阅收藏 ??








































































专栏系列(点击解锁)

学习路线(点击解锁)

知识定位

?Redis从入门到精通与实战?

Redis从入门到精通与实战

围绕原理源码讲解Redis面试知识点与实战

?MySQL从入门到精通?

MySQL从入门到精通

全面讲解MySQL知识与企业级MySQL实战

?计算机底层原理?

深入理解计算机系统CSAPP

以深入理解计算机系统为基石,构件计算机体系和计算机思维

Linux内核源码解析

围绕Linux内核讲解计算机底层原理与并发

?数据结构与企业题库精讲?

数据结构与企业题库精讲

结合工作经验深入浅出,适合各层次,笔试面试算法题精讲

?互联网架构分析与实战?

企业系统架构分析实践与落地

行业最前沿视角,专注于技术架构升级路线、架构实践

互联网企业防资损实践

互联网金融公司的防资损方法论、代码与实践

?Java全栈白宝书?

精通Java8与函数式编程

本专栏以实战为基础,逐步深入Java8以及未来的编程模式

深入理解JVM

详细介绍内存区域、字节码、方法底层,类加载和GC等知识

深入理解高并发编程

深入Liunx内核、汇编、C++全方位理解并发编程

Spring源码分析

Spring核心七IOC/AOP等源码分析

MyBatis源码分析

MyBatis核心源码分析

Java核心技术

只讲Java核心技术

发表评论

表情:
评论列表 (有 0 条评论,129人围观)

还没有评论,来说两句吧...

相关阅读