Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么ConcurrentHashMap.Segment和ConcurrentHashMap.HashEntry类是静态的?_Java_Design Patterns_Concurrency - Fatal编程技术网

Java 为什么ConcurrentHashMap.Segment和ConcurrentHashMap.HashEntry类是静态的?

Java 为什么ConcurrentHashMap.Segment和ConcurrentHashMap.HashEntry类是静态的?,java,design-patterns,concurrency,Java,Design Patterns,Concurrency,为什么ConcurrentHashMap.Segment和ConcurrentHashMap.HashEntry类是静态的? 为什么这样设计?基本上,所有不需要使用其封闭类属性的内部类都应该是静态的。这来自java中的一般原则,即每个对象都应该能够访问尽可能少的其他对象。每个内部非静态类都包含一个不可见的字段此$,该字段引用其父对象(ConcurrentHashMap),每个实体的开销为8字节(Segment或HashEntry)。这是访问父类字段的方式-内部类在某种程度上是属于单个容器(例如父

为什么
ConcurrentHashMap.Segment
ConcurrentHashMap.HashEntry
类是静态的?
为什么这样设计?

基本上,所有不需要使用其封闭类属性的内部类都应该是静态的。这来自java中的一般原则,即每个对象都应该能够访问尽可能少的其他对象。

每个内部非静态类都包含一个不可见的字段
此$
,该字段引用其父对象(
ConcurrentHashMap
),每个实体的开销为8字节(
Segment
HashEntry
)。这是访问父类字段的方式-内部类在某种程度上是属于单个容器(例如父类)的对象的语法糖


这就是为什么在可能的情况下应该用静态内部类替换内部类。

@Andrey,@Adam我同意你提出的观点,但我从有效的java书籍中得到的真正答案是。第22项倾向于静态成员类而不是非静态成员类

私有静态成员类的一个常见用途是表示 由其封闭类表示的对象的组件。对于 例如,考虑一个将键与值关联的MAP实例。 许多映射实现都有一个内部条目对象 映射中的键值对。当每个条目都与映射关联时, 条目上的方法(getKey、getValue和setValue)不需要 访问地图。因此,使用非静态 表示条目的成员类:私有静态成员类是 最好的

如果声明的成员类不需要访问 封闭实例时,始终将静态修饰符放在其声明中。如果省略此修饰符,则每个实例都将 具有对其封闭实例的无关引用


我从第22项中得到了更多的好东西,但以上是要点。

内部静态类有一个很好的特性,即它们是延迟加载的,正如我们在实现单例模式时在实现中解释的那样


静态内部类提供的其他功能是无法访问外部实例变量。从这里,我们也不能访问非静态方法。不需要创建单独的实例来初始化该静态类,直接使用
ClassName.InnerStaticClass.method()
,可以调用该方法。

但它增加了从其他类访问内部类的另一种可能性。“它”指的是这些类的当前实现。“它”表示这些类的当前实现。段的当前签名是“静态最终类段扩展ReentrantLock实现Serializabl”“所有不需要使用其封闭类的属性的内部类都应该是静态的”,如果这是原因,那么修改此静态内部类(ConcurrentHashMap.Segment)的可能性如何通过其他类,因为它不是私有的,这不是坏事吗?或者,如果作者有意将此功能提供给其他类,那么为什么呢?希望现在很清楚,它实际上是
包私有的
。如果你在JCF中查看其他类的代码,你会看到这一点。这可能是设计上的疏忽。这是一个很好的观点t如果这是这个类不是私有的原因呢?它是包本地的,就像包的私有一样。我不知道他们的意图是什么,但通常私有实体被设置为包本地的,以便进行单元测试,以便可以从不同的类访问它们(单元测试)。最有可能是出于测试目的,只有java人才不会玩设计,我不知道如何询问作者Doug Lea。你可以尝试通过邮件列表联系他们。如果你在做TDD,那么可测试性是设计中非常重要的一部分,
是合同的一部分,而不是实现的一部分。另一个原因是sac通过引入
sun.misc.Unsafe
对性能造成的影响非常巨大-
ConcurrentHashMap
真的很难阅读,相比之下,包私有可见性是一个微小的牺牲。