Java 静态嵌套类和常规类之间的区别
我知道这是一个有点重复的问题,但为了澄清一个非常重要的问题,我想以一种非常具体的方式提出这个问题。主要的问题是:当一个是静态嵌套类,而另一个是常规的顶级类,而不是访问包含类中的私有静态字段时,在其他方面相同的类之间是否有任何区别Java 静态嵌套类和常规类之间的区别,java,class,Java,Class,我知道这是一个有点重复的问题,但为了澄清一个非常重要的问题,我想以一种非常具体的方式提出这个问题。主要的问题是:当一个是静态嵌套类,而另一个是常规的顶级类,而不是访问包含类中的私有静态字段时,在其他方面相同的类之间是否有任何区别 // ContainingClass.java public class ContainingClass { private static String privateStaticField = ""; static class ContainedSt
// 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
关键字声明该类不是内部类:它实际上是封闭类范围内的外部类
请参见一个细微的区别是嵌套类能够创建封闭类型的成员:
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
}
}
}
但这也与类的范围有关。ContainedStaticClass具有包私有(即默认)可见性,OutsideClass具有公共可见性
您可以选择将ContainedStaticClass设置为protected或private,这不是OutsideClass的选项。另一个细微的区别出现在反射用例中。您需要使用
class.forName
加载类的类名有点古怪
Class.forName("com.acme.OuterClass.Innerclass"); // not found
Class.forName("com.acme.OuterClass$Innerclass"); // correct
另见:
有几个细微的差别 可能最重要的一点是嵌套的静态类可以设置为
私有的
或受保护的
。顶级类只能是包私有类或公共类
我能想到的其他差异是技术细节,在这些细节重要的地方,您可能不应该编写代码:
- 嵌套的静态类可以包含其他同名的类。当嵌套的静态类与外部类具有相同的名称,并且两者都在范围内时,嵌套的静态类将隐藏外部类
- 嵌套的静态类是由其外部类的子类定义的,因此它在这些子类的作用域中,可以在没有完全限定名或静态导入的情况下引用
- 同一个包中的两个外部级别类不能共享相同的名称,但一个类可以继承多个相同名称的嵌套静态类(例如,来自两个接口)。这不会导致编译错误,除非嵌套类的名称不正确
- 嵌套的静态类可能由于继承而具有多个不同的属性,例如在
类类A中{static class B extensed A{}
可以称为A.B
,A.B.B
,等等。外部类只能有一个完全限定名A.B.B
- 外部类的名称等于其名称,但嵌套静态类的规范名称不等于其二进制名称。嵌套静态类的二进制名称使用符号
将外部类的二进制名称与嵌套静态类的简单名称分开$