为什么枚举的构造函数不能访问静态字段? [英] Why can't enum's constructor access static fields?

查看:92
本文介绍了为什么枚举的构造函数不能访问静态字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我想要做的是将我的枚举实例存储在静态地图中。考虑这个示例代码,它允许通过缩写查找:

  public enum Day {
星期日(Sun),星期一(星期二)(星期二)(星期二)(星期二),星期三(星期二),星期三

private final String缩写;

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

私人日(字符串缩写){
this.abbreviation =缩写;
ABBREV_MAP.put(缩写,this); //无效
}

public String getAbbreviation(){
return缩写;
}

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

这不会工作,因为枚举不允许静态在其构造函数中引用。然而,它只是发现如果实现为一个类:

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


解决方案

构造函数是在静态字段全部被初始化之前被调用,因为静态字段(包括表示枚举值的那些)以文本顺序被初始化,并且枚举值总是来自其他字段。请注意,在您的类示例中,您没有显示ABBREV_MAP初始化的位置 - 如果在 SUNDAY之后是,则在初始化类时将会收到异常。



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



然而,我的经验中通常的答案是有一个code> static {} 阻止在所有静态初始化器的末尾,并使用 EnumSet.allOf 获取所有静态初始化所有的值。


Why can't enum's constructor access static fields and methods? This is perfectly valid with a class, but is not allowed with an enum.

What I'm trying to do is store my enum instances in a static Map. Consider this example code which allows lookup by 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);
    }
}

This will not work as enum doesn't allow static references in its constructor. It however works just find if implemented as a class:

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
}

解决方案

The constructor is called before the static fields have all been initialized, because the static fields (including those representing the enum values) are initialized in textual order, and the enum values always come before the other fields. Note that in your class example you haven't shown where ABBREV_MAP is initialized - if it's after SUNDAY, you'll get an exception when the class is initialized.

Yes, it's a bit of a pain and could probably have been designed better.

However, the usual answer in my experience is to have a static {} block at the end of all the static initializers, and do all static initialization there, using EnumSet.allOf to get at all the values.

这篇关于为什么枚举的构造函数不能访问静态字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆