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

public class Person {
  enum Gender {
    MALE,
    FEMALE,
    OTHER
  }
  ...
}

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

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


跟进:

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

TBH,不要指望创建内部类对象的语法会如此奇怪.但考虑到我们通常只在外部类中使用它,比如迭代器在不同的数据 struct 中的使用方式,我对此感到奇怪仍然是有道理的.


关于@Zabuzard和@user207421之间的讨论,两者都提出了一个很好的观点.user207421指出,类只有在非静态时才被认为是内部的.枚举和记录本质上是静态的:Oracle doc.从根本上学习是好的.但我很欣赏扎布扎德以一种我们可以轻松理解的方式解释一切.

推荐答案

解释

嵌套枚举本质上是static个嵌套类.它们不属于外部类的实例.

不管你创造了多少人,你总是只有singleenum Gender个左右浮动,就是这样.

它的值也是一样,这个枚举只有3个值——不管你创建了多少人.

内部类

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

class A {
  class B { ... }
  ...
}

您将只有一个B in memory类(如您所言).基本上只有一个类.

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

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

静态嵌套与解耦

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

class A {
  static class B { ... }
}

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

class A { ... }
class B { ... }

就主题而言,筑巢表明它们在某种程度上属于彼此.例如Map中的Entry类.


关于效率的说明

实际上,你应该停止在这些小事上为efficiency操心.相反,为读者想想readability个.

按照你的 idea ,效率是rarely ever a factor.如果,通常仅在整个代码库中的very small spot中(通常使用探查器识别).

所以基本上,除非你有一个很好的理由不这样做,否则总是strive for个简单易懂的解决方案.

Java相关问答推荐

为什么JFrame paint()多次绘制同一点(或根本不绘制)?

JPackage-results已安装-如何添加系统属性?

如何为具有多对多关系的实体的给定SQL查询构建JPA规范?

为什么我的在一个范围内寻找素数的程序不能像S所期望的那样工作

如何使用SpringBoot中的可分页对整数作为字符串存储在数据库中时进行排序

使用UTC时区将startDatetime转换为本地时间

JOOQ中的子查询使用的是默认方言,而不是配置的方言

Spring Security不允许加载js

在Frege中,我如何将一个字符串安全地转换为一个可能的Int?

在Oracle JDBC连接中,连接失效和身份验证失效是什么意思?

垃圾收集时间长,会丢弃网络连接,但不会在Kubernetes中反弹Pod

Java.lang.invke.LambdaConversionException:实例方法InvokeVirtual的参数数量不正确

Java组件项目中的JavaFX对话框国际化

带有可选部分的Java DateTimeForMatter

JFree Chart从图表中删除边框

如果执行@BeForeEach#repository.save(),则测试中的UnitTest最终UUID会发生更改

使IntelliJ在导入时优先 Select 一个类或将另一个标记为错误

在实例化中指定泛型类型与不指定泛型类型之间的区别

本机方法(JNI)总是编译的吗?

使用DynamoDB增强客户端时未更新属性