在Gradle中,如何仅包含库中的特定类,而不是添加整个依赖项?

后端开发 2026-07-08

我在做一个项目,只需要第三方库中的少量特定类。但是,当我在Gradle中添加依赖时,它包含了整个库。有没有办法在Gradle中只导入或包含库的某些特定类或部分,而不是整个依赖?

解决方案

如果它们是具体的小类(例如文本处理相关的类),你可能应该直接把它们拷贝下来。

通常会有功能极其丰富的库。要不要实际包含它们,取决于你。

使用这个库,你的代码会更稳定、经过更多测试、投入也更充分,只需简单地点击/引入即可。

然而,你得到的是库的全部内容,数量往往相当大(看着你,Guava... ;))。

不仅会增加体积(可能还会带来额外的下游依赖,进一步拖慢启动速度),还会增加维护成本——如果你升级SDK,这个库会继续工作吗?会不会存在漏洞?而且还存在潜在的供应链攻击风险。

过去人们常常随便地包含整个库。如今,缺点更受关注,对于简单的功能,代码通常会被复制/重新封装。

备选方案

你要的其实并没有实际意义。

要解释清楚,我们先需要介绍一个概念。

传递依赖

有一种叫做“传递依赖”的概念。库就是一个项目,项目也可以有依赖。所谓传递依赖是:

  • 你使用的某个库的依赖(即依赖的依赖)……
  • 但你的项目并不需要知道它。

构建系统通常的工作方式是自动处理——传递依赖会在运行时同样出现,因为原因同样:如果你的某个依赖在你尝试运行时不在类路径上,你的依赖也不会工作,因此如果它的某个依赖缺失,它也不会工作。

你这个想法的根本问题

一个项目(比如你正在使用的库)显然充满了“自身内部的依赖”。而且这些依赖会不断变化,且没有统一的规范(没有明确的规格)。

在你自己的代码中,名为 A.java 的源文件有多频繁地引用整个项目中的任何其他源文件?我猜这是一个很高的数字;绝大多数项目都会报告一个非常大的数字。这些就是“在项目中的传递依赖”。

因此,如果你真的得到了你想要的——一个能把你未使用的内容“剥离”的工具,那么你实际使用的类文件之所以能够工作,是因为它们的内部依赖也在;一旦去除了这些内部依赖,它们就无法工作。

进阶思考:树摇

理论上这是一个可解决的问题:从你实际需要的代码开始,然后让某个工具对代码进行扫描,自动确定为了让你明确列出的初始类集合工作而必须存在的其他类。

这被称为“树摇”。

除非一个库被明确设计成与这一概念兼容,否则要真正实现它并不可行——例如存在服务提供者加载(service loaders)和反射加载,会让树摇算法变得困难。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章