Difference between static nested class and regular class

前端 未结 5 1128
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-11 07:52

I know this is a bit of a duplicate question but I want to ask it in a very specific way in order to clarify a very important point. The primary question being: Is there any

相关标签:
5条回答
  • 2020-12-11 08:19

    ContainedStaticClass has package private (i.e. default) visibility and OutsideClass has public visibility.

    You could have chosen to make ContainedStaticClass protected or private which were not options for OutsideClass.

    0 讨论(0)
  • 2020-12-11 08:27

    Another subtle difference occurs in reflective use-cases. The class name you need to load a class with Class.forName is a bit funky.

    Class.forName("com.acme.OuterClass.Innerclass");  // not found
    Class.forName("com.acme.OuterClass$Innerclass");  // correct
    

    See also: Instantiate nested static class using Class.forName.

    0 讨论(0)
  • 2020-12-11 08:28

    Your statement is correct: the only difference between a static class and and a outer class is access to the class and the members of the enclosing class. The static keyword is declaring that the class is not an inner class: it is in effect an outer class within the scope of the enclosing class.

    See https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.5.1

    0 讨论(0)
  • 2020-12-11 08:29

    There are several subtle differences.

    Probably the most important one is that a nested static class can be made private or protected. A top-level class can only be package-private or public.

    The other differences I can think of are technical details, which you probably should not write code where those details matter:

    • A nested static class can "hide" or "shadow" other classes of the same name. When a nested static class has the same name as an outer class, and both are in scope, the nested static class hides the outer class.

    • A nested static class is inherited by subclasses of its outer class, so it is in scope in those subclasses and can be referred to without a fully-qualified name or a static import.

    • Two outer-level classes in the same package cannot share the same name, but a class can inherit multiple nested static classes of the same name (e.g. from two interfaces). This does not result in a compilation error unless the nested class's name is used ambiguously.

    • A nested static class can have multiple different fully-qualified names due to inheritance, for example in class A { static class B extends A {} } the class A.B can be referred to as A.B.B, A.B.B.B, and so on. An outer class can only have one fully-qualified name.

    • An outer class's canonical name equals its binary name, but a nested static class's canonical name is not equal to its binary name. The binary name of a nested static class has the symbol $ separating the outer class's binary name from the nested static class's simple name.

    0 讨论(0)
  • 2020-12-11 08:38

    A subtle difference is that a nested class has the ability to shadow members of the enclosing type:

    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
            }
        }
    }
    

    But that's also related to the scope of the class.

    0 讨论(0)
提交回复
热议问题