代码之家  ›  专栏  ›  技术社区  ›  Joonas Pulakka

Java类加载器是否保证不加载未使用的类?

  •  12
  • Joonas Pulakka  · 技术社区  · 14 年前

    有没有保证(默认,系统)Java类加载器 是否尝试加载正在运行的代码中未引用的类?举几个例子来说明我的意思:

    • framework.jar 我知道其中包含对另一个的引用 library.jar 的类,但我只使用框架中不包含这些引用的部分。离开安全吗
    • 静态块在第一次加载类时运行。如果没有正在运行的代码包含对特定类的引用,是否确定它的静态块没有运行?

    快速测试它似乎可以像上面假设的那样工作,而且加载未使用的类也没有多大意义,但是有没有其他的呢 保证 关于这个?

    附加: 似乎我上面的“静态块在第一次加载类时运行”语句有点不正确。绝对有可能 课程(一件事)没有 跑步 他们(另一件事)。所以我对这两种情况都感兴趣;关于类不能得到 加载 运行

    7 回复  |  直到 14 年前
        1
  •  8
  •   Community dbr    4 年前

    没有这样的保证 1 wrt类的加载。

    但是,可以保证静态块不会过早运行。触发类初始化的事件在中指定 JLS 12.4.1 .

    类或接口类型T将在第一次出现以下任一情况之前立即初始化:

    • T是一个类,调用由T声明的静态方法。
    • 分配一个由T声明的静态字段。
    • T是一个顶级类,是一个assert语句(§14.10)执行T中的词汇嵌套。

    1-据观察,当前一代Java实现不会不必要地加载类,但这并不能保证。唯一的保证就是它在官方规范中写的内容。

        2
  •  4
  •   josefx    14 年前

    爪哇 specification

    类加载器及其应用 ClassLoader可以实现不同的 缓存的二进制表示 类和接口,预取它们 基于预期用途,或加载

    因此类加载器可以自由地预取类文件。

    类或接口类型T将 第一次出现

    • T是一个类,创建了一个T的实例。
    • 分配一个由T声明的静态字段。

    静态块将仅在类首次使用时执行。

        3
  •  1
  •   Donal Fellows    14 年前

    我不认为有任何这样的保证。首先,我见过代码扫描器,它可以在应用程序启动期间处理整个包层次结构/jar中的注释;他们马上就会违背这个假设。

    为什么这很重要?你通常是在高度可控的系统加载之后,所以任何重要的地方都是你无论如何都想强迫它的地方

        4
  •  1
  •   Thorbjørn Ravn Andersen    14 年前

    但是请注意,有新的方法来注册服务,例如通过META-INF。这些类也需要加载。

        5
  •  1
  •   mdma    14 年前

    如果不使用反射,则可以使用死代码移除工具静态检查使用了哪些类,例如 ProGuard . 它将分析您的代码并确定使用的所有类。在此基础上,删除未使用的代码,包括库中未使用的代码。

        6
  •  0
  •   raja kolluru    14 年前

    没有其他海报提到的那种保证。但你的问题和你关心的问题并不一致。让你离开library.jar 出去,你不需要这样的保证。

    有许多框架可以在运行时发现是否存在其他框架。例:Commons日志记录发现了一堆其他框架。springwebflow在运行时发现脚本框架是什么(例如OGNL)。这些框架显然是使用所有依赖框架编译的,但它们不必在运行时存在。

        7
  •  0
  •   OscarRyz    14 年前

    对。

    想想下面这些。如果你添加以下代码 library.jar 班级:

     public ShutDown {static { System.exit(-1); }}
    

    默认系统不会自动加载该代码,因为现有代码都没有引用或不知道 ShutDown 类,也没有加载它的方法,而且Java类加载器并不只是从jar中随机加载类。

    前面的答案中描述了类的加载方式,如果您仔细查看,其中没有一个包含 “如果jar中有类,它将被加载”