5

Why ConcurrentHashMap.Segment and ConcurrentHashMap.HashEntry classes are static? Why it is designed in this way ?

Adam Arold
  • 29,285
  • 22
  • 112
  • 207
Vipin
  • 4,851
  • 3
  • 35
  • 65

4 Answers4

6

Basically all inner classes which does not need to use the properties of their enclosing classes are supposed to be static. This comes from the general principle in java which says that every object should have access to the least possible other objects.

Adam Arold
  • 29,285
  • 22
  • 112
  • 207
  • but it adds one more possibility of accessing inner class from some other class. – Vipin Nov 21 '13 at 15:18
  • What do you refer to by "**it**"? – Adam Arold Nov 21 '13 at 15:21
  • "it" means current implementation of these classes . current signature for segment is "static final class Segment extends ReentrantLock implements Serializabl" – Vipin Nov 21 '13 at 15:35
  • "all inner classes which does not need to use the properties of their enclosing classes are supposed to be static" , if this was the reason then how about possibility of modifying this static inner class ( ConcurrentHashMap.Segment ) by other classes as it is not private , isn't is bad? Or if author deliberately wanted to give this functionality to other classes then why ? Hope it is clear now – Vipin Nov 21 '13 at 16:12
  • It is actually `package private`. If you look at the code of other classes in the JCF you see this all over the place. It might be a design oversight. – Adam Arold Nov 21 '13 at 16:18
2

Each inner non-static class contains an invisible field this$ which references it's parent object (ConcurrentHashMap) which creates an overhead of 8 bytes per entity (Segment or HashEntry). This is how parent's class fields are accessed - inner class is in some sort a syntax sugar for objects which belong to a single container (e.g. parent).

This is why inner classes should be replaced with static inner classes when possible.

Andrey Chaschev
  • 16,160
  • 5
  • 51
  • 68
  • This is one good point but if it is the reason why this class is not private? – Vipin Nov 21 '13 at 16:16
  • It's package-local which is like private for a package. I don't know what was their intention, but usually private entities are made package-local for unit-testing so that one could access them from a different class (a unit test). – Andrey Chaschev Nov 21 '13 at 16:19
  • most probably for testing purpose only java guys will not play with design , I don't know how can ask author Doug Lea. – Vipin Nov 23 '13 at 06:29
  • You may try reaching them at the mailing list. If you're doing TDD, then testability is a very important part of your design and `Segment` is a part of a contract not of an implementation. Another reason is that the sacrifice made to performance by introducing `sun.misc.Unsafe` was very huge - `ConcurrentHashMap` is really hard to read, compared to that package-private visibility is a tiny sacrifice if at all. – Andrey Chaschev Nov 23 '13 at 10:33
1

@Andrey , @Adam I agree the points you presented but the real answer I got from effective java book. Item#22 Favor static member classes over nonstatic.

A common use of private static member classes is to represent components of the object represented by their enclosing class.For example, consider a Map instance, which associates keys with values. Many Map implementations have an internal Entry object for each key-value pair in the map. While each entry is associated with a map, the methods on an entry (getKey, getValue, and setValue) do not need access to the map. Therefore, it would be wasteful to use a nonstatic member class to represent entries: a private static member class is best.

If you declare a member class that does not require access to an enclosing instance, always put the static modifier in its declaration.If you omit this modifier, each instance will have an extraneous reference to its enclosing instance

lot more good stuff I got from item#22 but above are the main points.

Community
  • 1
  • 1
Vipin
  • 4,851
  • 3
  • 35
  • 65
0

Inner static class has a one beautiful feature that they are lazy loaded as it is explained in Bill Pugh Singleton Implementation, when we implement singleton pattern.

Other features that the static inner class provides is that the outside instance variables are not accessible. From here, we can not access non static methods either. There is no need to make separate instance to initialize that static class, Directly using ClassName.InnerStaticClass.method(), the method can be called.

hi.nitish
  • 2,732
  • 2
  • 14
  • 21