使用位移表示法定义 Java 常量

Defining Java Constants using Bit-Shift Notation

我正在查看 java.util.HashMap class 的源代码并注意到显式无参数构造函数需要两个常量:

/**
 * Constructs an empty <tt>HashMap</tt> with the default initial capacity
 * (16) and the default load factor (0.75).
 */
public HashMap() {
    this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
}

但是当我查看DEFAULT_INITIAL_CAPACITY常量时,我​​发现它的定义如下:

/**
 * The default initial capacity - MUST be a power of two.
 */
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

我从未在我从事的任何产品中看到过这种类型的结构,并且在 Java Language Specification 或通过谷歌搜索中找不到任何结果。所以我查看了字节码,但我发现使用 161 << 4 提供了相同的输出,这意味着(至少在我的极简主义情况下)编译器会将后者转换为十进制表示法。两个版本的字节码都包含定义:

javap -c -verbose /---/myClass.class
----
public static final int i;
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
ConstantValue: int 16

所以我欢迎任何关于这个成语 necessity/use 的反馈。

必要性很简单:左移 1 生成的常数,例如 1 << N 将始终是 2 的幂。

这在定义掩码时很有用,或者在 HashMap 情况下,在分配一定数量的对象时(通过缓存和类似的低级问题)是更好的可优化值(通过缓存和类似的低级问题)。

只是为了澄清一件事,你说:

meaning that (at least in my minimalist case) the compiler will convert the latter to decimal notation

这不是事实,重要的是存储的值,它本身没有符号。 161<<4 具有相同的语义值,它们在文本上的表示方式与它无关。

它完全等价,但以这种方式编写是为了更清楚地说明值的来源和计算方式——在本例中,它的本意是 2^4。

它可以用任何一种方式编写,作者只是认为这会更加自我记录。