内部枚举或类有效吗?

Sta*_*tan 2 java performance enums inner-classes

我经常看到人们使用内部枚举,例如:

public class Person {
  enum Gender {
    MALE,
    FEMALE,
    OTHER
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)

我不确定它内部是如何工作的,所以我想知道每次有人创建一个新人时是否会有这个枚举类的新实例,例如new Person()

内部枚举会继续消耗更多内存还是只有一个?


跟进:只需在代码编辑器(Java 11)中对接受的答案进行快速测试:

public class Person {
    String name;
    int Age;
    Address address = new Address();//Usual way we see
    public class Address {
        String city;
        String Country;
        int number;
    }
}

public class test {
    public static void main(String[] args) {
        var a = new Person.Address();//complains "innerclass.Person' is not an enclosing class, make Address Static"
        var p = new Person();
        var a1 = p.new Address();//correct syntax to create inner clas object outside its outer class
    }
}
Run Code Online (Sandbox Code Playgroud)

老实说,永远不要期望创建内部类对象有如此奇怪的语法。但考虑到我们通常只是在外部类中使用它,就像迭代器在不同的数据结构中使用一样,我对此感到奇怪仍然是有道理的。最后,内部类对象是根据实际需要以及对外部类的依赖来创建的,所以不存在效率问题


关于@Zabuzard 和@user207421 之间的讨论,两者都提出了很好的观点。user207421 指出,只有当类是非静态的时,类才被视为内部类。Enum 和 Record 本质上是静态的:Oracle doc。从根源上学习是好的。但我确实很欣赏扎布扎德如何以一种我们可以从头开始轻松理解的方式解释一切。

Zab*_*uza 7

解释

嵌套枚举本质上是静态嵌套类。它们不属于外部类的实例。

无论你创造了多少人,你永远只有一个 enum Gender在周围漂浮,就是这样。

它的值也是如此,这个枚举只有 3 个值 - 无论您创建了多少人。

内部类

但是,即使您有一个内部(非静态)类,例如

class A {
  class B { ... }
  ...
}
Run Code Online (Sandbox Code Playgroud)

B 您的内存中只会有一个班级(正如您所说的那样)。本质上总是只有一个类。

现在,当您创建 的实例时B,您必须基于先前创建的 实例来创建它们A,因为Bnow 的实例属于 的实例A并且只能存在于其上下文中。

因此,它们还共享该特定实例的非静态属性A。您经常会看到它被用于Iterator数据结构的实现。

静态嵌套与解耦

如果您有一个静态嵌套类,例如

class A {
  static class B { ... }
}
Run Code Online (Sandbox Code Playgroud)

您可能会问,与真正完全解耦它们唯一真正的区别是什么,如

class A { ... }
class B { ... }
Run Code Online (Sandbox Code Playgroud)

嵌套清楚地表明它们在某种程度上在主题方面属于彼此。一个例子是Entry中的类Map


关于效率的说明

实际上,您应该停止担心这些小事情的效率。相反,请考虑读者的可读性。

按照您的想法,效率很少是一个因素。如果,通常只在整个代码库中的一个非常小的位置(通常使用分析器来识别)。

因此基本上,除非您有充分的理由不这样做,否则请始终努力寻求最具可读性和可理解性的解决方案。