为什么LinkedBlockingQueue的头不是私有的?

fjd*_*gsd 3 java blockingqueue

我正在阅读 LinkedBlockingQueue 代码(JDK8u),我发现 LinkedBlockingQueue 的 head 字段不是私有的,但最后一个字段是私有的。我找不到 head 的任何特定操作。那么为什么不将 head 设置为私有呢?

/**
 * Head of linked list.
 * Invariant: head.item == null
 */
transient Node<E> head;

/**
 * Tail of linked list.
 * Invariant: last.next == null
 */
private transient Node<E> last;
Run Code Online (Sandbox Code Playgroud)

Ste*_*n C 5

首先是一些事实。

  1. 在 Java 6 中,该head字段是private.
  2. 到了 Java 17,该head字段是包私有的……并且它有关于不变量的注释。
  3. 这个变化实际上发生在 Java 8 中。

那么他们为什么要改变它呢?

到目前为止我还没有弄清楚,但可能的原因可能包括:

  • 这样子类(在同一个包中)就可以访问该字段,尽管我在已发布的代码库中看不到任何此类类。
  • 为了更方便地测试课程。(这不是进行此更改的理由,而且我看不到任何证据表明这是原因。)
  • 这是与内部类相关的“个人风格”,尽管我不相信。(为什么只是这样做head?为什么不呢tail?)
  • 这是偶然发生的。

在花了 20 分钟查看 Github 上的历史记录后,我认为这可能是一个意外。更改似乎发生在这个提交中(https://github.com/openjdk/jdk8u/commit/6f31fa54ac050d781656d6e8ed18a40b55ef5c0d)......根据“gitblame”。但是当我查看提交中的内容时,我根本看不到更改,更不用说目的1了。这真是令人费解。

也许在 Mercurial 历史2中更清楚。

无论如何,这整件事都是好奇心的锻炼。他们为什么改变它并不重要,并且它不会影响他们所做的任何用户代码3


1 - 变更集描述表明它只是与类的原始/主要作者维护的私有存储库同步java.util.concurrent
2 - 我们正在寻找权威 Mercurial 存储库的只读 Git 镜像。镜子的创建过程中可能出现了一些问题。
3 - ...与用户代码中已存在的 Heisenbug 进行模交互。