[英]Difference between static nested class and regular class
我知道這是一個有點重復的問題,但我想以非常具體的方式提出這個問題,以澄清一個非常重要的觀點。 主要問題是:除了訪問包含類中的私有靜態字段之外,當一個是靜態嵌套類而另一個是常規的頂級類時,其他相同的類之間是否有任何區別?
// ContainingClass.java
public class ContainingClass {
private static String privateStaticField = "";
static class ContainedStaticClass {
public static void main(String[] args) {
ContainingClass.privateStaticField = "new value";
}
}
}
// OutsideClass.java
public class OutsideClass {
public static void main(String[] args) {
ContainingClass.privateStaticField = "new value"; // DOES NOT COMPILE!!
}
}
換句話說:是ContainedStaticClass
可以訪問或執行的操作與OutsideClass
可以訪問或執行的操作之間的唯一區別,即OutsideClass
不能直接訪問ContainingClass.privateStaticField
嗎? 或者還有其他不常被討論或遇到的細微差別嗎?
您的說法是正確的:靜態類和外部類之間的唯一區別是對類和封閉類的成員的訪問。 static
關鍵字聲明該類不是內部類:它實際上是封閉類范圍內的外部類。
請參閱https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.5.1
ContainedStaticClass 具有包私有(即默認)可見性,而OutsideClass 具有公共可見性。
您可以選擇將 ContainedStaticClass 設為 protected 或 private,而這不是 OutsideClass 的選項。
一個微妙的不同之處在於一個嵌套類具有的能力陰影包封類型的成員:
class ContainingClass {
public static String privateStaticField = "a";
static class ContainedStaticClass {
public static String privateStaticField = "b";
public static void main(String[] args) {
System.out.println(privateStaticField); // prints b
}
}
}
但這也與類的范圍有關。
有幾個細微的差別。
可能最重要的一個是嵌套的靜態類可以設置為private
或protected
。 頂級類只能是 package-private 或public
。
我能想到的其他差異是技術細節,您可能不應該在這些細節重要的地方編寫代碼:
嵌套的靜態類可以“隱藏”或“隱藏”同名的其他類。 當嵌套靜態類與外部類同名且都在作用域內時,嵌套靜態類會隱藏外部類。
嵌套靜態類由其外部類的子類繼承,因此它在這些子類的范圍內,無需完全限定名稱或靜態導入即可引用。
同一個包中的兩個外層類不能共享同名,但一個類可以繼承多個嵌套的同名靜態類(例如從兩個接口)。 這不會導致編譯錯誤,除非嵌套類的名稱使用不明確。
由於繼承的原因,嵌套的靜態類可以有多個不同的完全限定名稱,例如在class A { static class B extends A {} }
,類AB
可以稱為ABB
、 ABBB
等。 一個外部類只能有一個完全限定的名稱。
外部類的規范名稱等於其二進制名稱,但嵌套靜態類的規范名稱不等於其二進制名稱。 嵌套靜態類的二進制名稱使用符號$
將外部類的二進制名稱與嵌套靜態類的簡單名稱分隔開。
另一個微妙的區別發生在反射用例中。 使用Class.forName
加載類所需的類名有點時髦。
Class.forName("com.acme.OuterClass.Innerclass"); // not found
Class.forName("com.acme.OuterClass$Innerclass"); // correct
另請參閱: 使用 Class.forName 實例化嵌套靜態類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.