当前位置: 首页 > 面试题库 >

Java 为什么枚举的构造函数不能访问静态字段?

薛阳荣
2023-03-14
问题内容

为什么枚举的构造函数不能访问静态字段和方法?这对于一个类是完全有效的,但对于枚举是不允许的。

我正在尝试将枚举实例存储在静态Map中。考虑下面的示例代码,它允许通过abbreivation查找:

public enum Day {
    Sunday("Sun"), Monday("Mon"), Tuesday("Tue"), Wednesday("Wed"), Thursday("Thu"), Friday("Fri"), Saturday("Sat");

    private final String abbreviation;

    private static final Map<String, Day> ABBREV_MAP = new HashMap<String, Day>();

    private Day(String abbreviation) {
        this.abbreviation = abbreviation;
        ABBREV_MAP.put(abbreviation, this);  // Not valid
    }

    public String getAbbreviation() {
        return abbreviation;
    }

    public static Day getByAbbreviation(String abbreviation) {
        return ABBREV_MAP.get(abbreviation);
    }
}

这将不起作用,因为枚举不允许在其构造函数中使用静态引用。然而,它只是在实现为类的情况下才起作用:

public static final Day SUNDAY = new Day("Sunday", "Sun");
private Day(String name, String abbreviation) {
    this.name = name;
    this.abbreviation = abbreviation;
    ABBREV_MAP.put(abbreviation, this);  // Valid
}

问题答案:

因为所有静态字段(包括表示枚举值的静态字段)都是按文本顺序初始化的,并且枚举值始终位于其他字段之前,所以在初始化静态字段之前会调用构造函数。请注意,在你的类示例中,你没有显示ABBREV_MAP的初始化位置-如果在 SUNDAY 之后,则在初始化类时会出现异常。

是的,这有点痛苦,可能设计得更好。

但是,根据我的经验,通常的答案是static {}在所有静态初始化程序的末尾添加一个块,然后在其中进行所有静态初始化,EnumSet.allOf 以获取所有值。



 类似资料:
  • 问题内容: 整个问题都在标题中。例如: 构造函数是细跟的缺省或修改,但如果考虑到给我一个编译器错误或改性剂。 问题答案: 将枚举视为具有有限数量实例的类。除了最初声明的实例外,再也没有其他实例了。 因此,您不能具有公共或受保护的构造函数,因为那样将允许创建更多实例。 注意:这可能不是官方原因。 但这对我来说最有意义。

  • 问题内容: 目前,我们的代码存在一种情况,即我们在Java层中使用枚举,该枚举通过以下构造函数存储id和“显示值”: 我们希望打字稿中的某些内容能够与之匹配,以便以有意义的方式显示状态以执行逻辑并在前端向用户显示值。这可能吗?有没有更好的方法来解决这个问题?我们希望避免使用诸如status.id()= 1或status.name()=’Active’这样的逻辑,从而推动枚举。 谢谢 问题答案: T

  • 问题内容: 这来自有效的Java: 请注意,操作常量是从创建常量之后运行的静态块放入stringToEnum映射中的。试图使每个常量从其自己的构造函数中放入映射中将导致编译错误。这是一件好事,因为如果合法,它将导致NullPointerException。除编译时常量字段外,不允许枚举构造函数访问枚举的静态字段。此限制是必需的,因为在构造函数运行时尚未初始化这些静态字段。 我的问题是关于这条线的:

  • 或修饰符不允许与构造函数一起使用。为什么?我试过阅读标准文档,但没有很好地理解它。

  • 我不确定我是否过度工程化了,但我正在考虑创建一个枚举,其中包含一个枚举列表作为它的值,从中我可以得到它的值。 我无法确定枚举的类型,以便正确地将值数组筛选到正确的枚举。例如,我可以用轻松地获得US枚举。我遇到的困难是从该数组中获得正确的值。我尝试比较名称,

  • 问题内容: 由于枚举构造函数只能由其常量调用,因此为什么要允许它成为包私有的? 问题答案: 构造函数实际上不是包私有的…隐式地意味着接口方法是隐式的,即使您不添加关键字也是如此。 JLS(第8.8.3节)的相关部分规定: 如果没有为普通类的构造函数指定访问修饰符,则该构造函数具有默认访问权限。 如果没有为枚举类型的构造函数指定访问修饰符,则构造函数为。 如果枚举类型(第8.9节)的构造函数声明为或