Java 静态内部类可以被实例化吗

2023/01/07 Java 共 2693 字,约 8 分钟

前言

静态让我下意识觉得这是不可以的。实例化,是面向对象的术语,类被实例化为对象。静态内容,是全局的,不需要通过实例就可以使用。

我询问了几个人,他们想法都和我差不多,我们的理解都有些偏差。这有必要仔细看看了。

例子

    public static void main(String[] args) {
        StaticTest.StaticNestedClass staticNestedClass = new StaticTest.StaticNestedClass();
        staticNestedClass.printI();
        StaticTest s = new StaticTest();
        StaticTest.NestedClass nestedClass = s.new NestedClass();
//        StaticTest.StaticNestedClass staticNestedClass=s.new StaticNestedClass();// 无法通过编译
        nestedClass.printI();
        nestedClass.printJ();
    }
public class StaticTest {

    public static int i = 1;
    private int j;

    public static class StaticNestedClass {
        public void printI() {
            System.out.println(i);
        }
        public void printJ() {
//            System.out.println(j); // 无法通过编译
        }
    }

    public class NestedClass {
        public void printI() {
            System.out.println(i);
        }

        public void printJ() {
            System.out.println(j);
        }
    }
}

 NestedClassStaticNestedClass
可否被实例化可以可以
可否访问外部类静态属性可以可以
可否访问外部类非静态属性可以不可以
实例化通过已经被实例化的外部类对象直接通过外部类

总结

可能是把静态和抽象搞混了,抽象类是不能被实例化的,静态和能否被实例化没有实在的关系。

StaticNestedClass中的 static,可能只是指不依赖外部类了,static 这个关键字和面向对象的关系并不是想象中那么强。

顺便,搜到的几个回答,看来迷惑的不只我一个人。

The significance of static with a class definition is not whether the class can be instantiated or not, but rather whether the class must be instantiated from within a non-static method of the outer class or not.

Non-static inner class instances are tied to the instance that created them – there’s a pointer in the inner class instance back to the creating instance (which is useful in a number of ways). Static inner class instances are not tied to the creating instance.

(I worked in the innards of the JVM for about 10 years and I still find this confusing.)

Yes, there is nothing in the semantics of a static nested type that would stop you from doing that. This snippet runs fine.

public class MultipleNested {
    static class Nested {
    }
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Nested();
        }
    }
}

See also

  • public static interface Map.Entry<K,V>
    • public static class AbstractMap.SimpleEntry<K,V>
      • Probably the most well-known nested type. Obviously instantiated multiple times.

Now, of course the nested type can do its own instance control (e.g. private constructors, singleton pattern, etc) but that has nothing to do with the fact that it’s a nested type. Also, if the nested type is a static enum, of course you can’t instantiate it at all.

But in general, yes, a static nested type can be instantiated multiple times.

Note that technically, a static nested type is not an “inner” type.

JLS 8.1.3 Inner Classes and Enclosing Instances

An inner class is a nested class that is not explicitly or implicitly declared static.

That is, according to JLS terminology, an inner class is one that isn’t static. If it’s static, then it’s just a nested type.


*So what does static mean?*

static simply means that the nested type does not need an instance of the enclosing type to be instantiated.

See also

reference

Can a class be instantiated as static in java? [duplicate]

Java: Static Class?

Can a Static Nested Class be Instantiated Multiple Times?

文档信息

Search

    Table of Contents