oop Bloch高效的Java更喜欢静态类而不是非静态类有多少实例?
我想知道封闭类可以创建多少个静态成员类实例。我假设只有一个,但是下面从布洛赫那里摘录的内容对我来说没有意义
引用Joshua Bloch的有效Java-Item 22*:喜欢静态成员类而不是非静态成员类
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 accidentally omit the static modifier in the entry declaration, the map will still work, but each entry will contain a superfluous reference to the map, which wastes space and time.
他指出,映射为映射中的每个键值对创建一个条目对象,即静态成员类的多个实例
所以我的假设是错误的!这意味着我对静态成员类的理解是错误的。每个人都知道静态成员变量的行为,例如经典的静态最终字符串-对象只有一个实例
这是否意味着在实例化封闭对象时,静态成员类实际上没有实例化
在这种情况下,使用静态成员类作为入口映射有什么意义?为什么不在API上使用接口呢?然后,每个其他Collections类都可以提供自己的实现
[*]刚刚意识到这是我所拥有的PDF版本书中的第18项
# 1 楼答案
这是因为,它使包结构在逻辑上正确
现在,这是一个没有人愿意卷入的设计讨论
# 2 楼答案
这是对
static
关键字的常见误解当您将
static
与一个变量一起使用时,它意味着这个类的所有对象都只有一个变量然而,在内部类的上下文中,它意味着完全不同的东西A
static
内部类与封闭类的对象没有连接,而非静态内部类与封闭类的对象没有连接一个
static
内部类:我的
TrieMap
类使用的Map.Entry
类不需要引用创建它的对象,因此可以使它static
保存不必要的引用非
static
内部类:StringWalker
对象内的CharacterIterator
引用要迭代为s
的字符串,该字符串在StringWalker
对象中只存在一次。因此,我可以创建一个StringWalker
的许多迭代器,它们都在相同的字符串中运行为什么会这样奇怪
这种看似不合逻辑的二元性源于在
C
中使用static
关键字在
C
中,您可以(或至少过去能够)执行以下操作:每次调用函数时,
x
都与上次一样,在本例中是递增的概念是
static
关键字表示变量的作用域由其封闭块封闭,但语义上由其父块封闭。即,上述代码大致相当于:但是
x
只允许在函数内部被引用把这个概念带到{}中去,现在事情变得更有意义了。
static
内部类的行为与在类外部声明的行为完全相同,而非static
内部类与其封闭实例的结合更紧密——事实上,它可以直接引用实例此外:
表现得很像
如果合法的话
这节课到此结束
# 3 楼答案
我认为Java团队把这个命名搞乱了。静态内部类(严格来说,它们的正确名称是“静态嵌套类”)与普通类没有任何区别,只是它有一个奇特的名称(
Something.MyClass
而不是MyClass
),并且可以私有化(即不能从其他类实例化)在
Map
的情况下,之所以选择它,完全是因为名称Map.Entry
表明Entry
与Map
相关。正如您所建议的,仅使用普通类进行此操作是完全合理的。唯一的区别是你不能写Map.Entry
我认为他们应该做的是为静态嵌套类使用“非静态”内部类(即封闭类中的
class
)的语法,而不是发明一个新的关键字来创建“非静态”内部类,因为这些类的行为不同于普通类。可能是attached class
之类的。当然,选择关键字static
是为了避免保留太多的关键字,但我认为这只会造成混乱# 4 楼答案
是的,无论嵌套类是静态的,您都可以拥有嵌套类的多个实例
当嵌套类是静态的时,您可以创建它的实例,而不需要封闭类的实例,这是好处之一,基本上是静态和非静态嵌套类之间的主要区别
当它的构造函数被调用时,它被实例化。与非静态类没有任何区别。当代码第一次访问嵌套类时,它本身由JVM加载。我认为,与其他类相比,这也没有什么不同(虽然不是100%确定,但您可以自己测试)。所以我认为您混合了“通过JVM加载类”和“实例化类”这两个术语
如上所述,创建静态嵌套类的实例更容易。您不需要一个封闭的实例,它有时(可能大多数时候)正是您想要的
另见:
(1) Nested Classes
(2) How can the JVM decide if a class is nested into another class?
(3) Loading of a nested class by the JVM
您可以沿着这些行搜索其他引用
参考文献(2)似乎是先进的,与你的问题无关