You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Maven项目依赖中同包类被本地类覆盖的行为名称及原理是什么?

问题场景

你有一个dependency项目,定义了如下两个类:

package it.dependency.common;

public class Consumer {
    public void consume() {
        Worker dependency = new Worker();
        dependency.work();
    }
}
package it.dependency.common;

public class Worker {
    public void work() {
        System.out.println("I'm doing things in the DEPENDENCY project");
    }
}

在dependency项目中运行调用consume()方法,会正常输出 I'm doing things in the DEPENDENCY project。

将该项目编译为JAR包后,导入名为test project的项目作为依赖,依赖配置如下:

<dependency>
    <groupId>org.example</groupId>
    <artifactId>dependency</artifactId>
    <version>1.0-SNAPSHOT</version>
    <systemPath>${lib.path}/dependency-1.0-SNAPSHOT.jar</systemPath>
</dependency>

test project中重定义了同包同名的Worker类:

package it.dependency.common;

public class Worker {
    public void work() {
        System.out.println("I'm doing things in the TEST project");
    }
}

此时在test project中调用dependency项目Consumer类的consume()方法,输出变为 I'm doing things in the TEST project。


行为名称

该行为叫做类覆盖(Class Shadowing),属于类路径冲突的典型场景,部分资料也会将其称为同全限定名类优先级覆盖。

底层运行原理

该现象是JVM类加载规则的正常表现,核心逻辑如下:

  • JVM判断类唯一性的依据是全限定类名(包名+类名)+ 加载类的类加载器实例,两个条件完全一致才会被判定为同一个类。该场景中的两个Worker类全限定名完全相同,且都由默认的应用类加载器(AppClassLoader)加载,因此JVM只会加载搜索顺序中第一个被找到的类。
  • 常规Maven项目运行时,应用类加载器的类搜索优先级为:当前项目编译输出的classes目录 > 依赖引入的第三方JAR包。test project中自定义的Worker类编译后存放在当前项目的classes目录下,优先级远高于外部引入的dependency JAR包里的同名类,因此会被优先加载。
  • 当Consumer类执行new Worker()逻辑时,会向类加载器请求加载it.dependency.common.Worker,类加载器会直接返回已经完成加载的test project中的Worker类,因此最终执行的是test project中的方法逻辑。

内容的提问来源于stack exchange,提问作者Marco Arnone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 06:45:06