Java 为什么要使用;“内部类”;而不是使用;新";直接的?

Java 为什么要使用;“内部类”;而不是使用;新";直接的?,java,guava,Java,Guava,当我学习番石榴时,我在com.google.common.hash.Hashing类中发现了如下代码: public static HashFunction crc32c() { return Crc32cHolder.CRC_32_C; } private static final class Crc32cHolder { static final HashFunction CRC_32_C = new Crc32cHashFunction(); } 我想知道,为什么不这样

当我学习番石榴时,我在com.google.common.hash.Hashing类中发现了如下代码:

public static HashFunction crc32c() {
    return Crc32cHolder.CRC_32_C;
}

private static final class Crc32cHolder {
    static final HashFunction CRC_32_C = new Crc32cHashFunction();
}
我想知道,为什么不这样写,这仅仅是作者的习惯吗?还是为了其他目的

public static HashFunction crc32c() {
    return new Crc32cHashFunction()
}

你的替代建议

public static HashFunction crc32c() {
    return new Crc32cHashFunction()
}
每次调用
crc322c()
时,将创建一个新的
Crc32cHashFunction
实例。如果每次调用都不需要返回新实例,那么在每次调用中返回相同的实例会更有效

使用静态final变量

static final HashFunction CRC_32_C = new Crc32cHashFunction();
是实现单个实例的一种方法


至于为什么
HashFunction
实例是嵌套类
Crc32cHolder
的成员(而不是外部类的成员),其动机可能是懒惰的求值-只有在第一次调用
crc32c()
方法时,将初始化
Crc32cHolder
类,并创建
Crc32cHashFunction
实例。因此,如果从未调用该方法,将永远不会创建
Crc32cHashFunction
(假设没有其他访问
Crc32cHolder
类的权限)

这里没有内部类。延迟加载之所以有效,是因为
crc32c
(以及它所包含的整个类)在签名中只讨论抽象的
HashFunction
,因此具体的
Crc32cHashFunction
类(及其实例持有者类)除非有人真正调用该方法,否则不需要解析。但是,您知道为什么单例不只是
Crc32cHashFunction
上的静态字段吗?额外的holder间接寻址给表带来了什么?@Thilo我不知道这里的用例(我没有时间深入研究代码),但也许他们不希望在首次访问
Crc32cHashFunction
类时初始化静态字段。我不知道还有什么其他代码可能在使用
Crc32cHashFunction
——也许这些其他代码没有使用那个单一实例(例如,在一些用例中,
Crc32cHashFunction
类被初始化,但您不想初始化那个静态变量)。@Thilo看看如何操作(有一个bug导致它非常慢,但即使没有它,也需要一些不可忽略的时间)和(出于兼容性原因,导致加载的遗留常量仍然存在)。