如何定义枚举项的属性 [英] How to define properties for Enum items

查看:28
本文介绍了如何定义枚举项的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已阅读问题 Java 和 C++ 之间的 Enum 的区别? 但我还是很困惑.

I have read the question Difference of Enum between java and C++? but I'm still confused.

我希望以下内容返回相关的字符串:

I would like the following to return the related String:

public enum Checker {
    EMPTY ("Empty"),
    RED ("Red"),
    YELLOW ("Yellow");
}

据我所知,这应该是可能的.只是希望您对如何实施它有所了解.

From what I have read, this should be possible. Just would like you to shed some light on it on how to implement it.

推荐答案

简答

您需要一个构造函数、一个字段和一个 getter.

Short Answer

You need a constructor, a field and a getter.

枚举类型可以有构造函数,前提是它们的访问级别是私有的或默认的(包私有的).您不能直接调用这些构造函数,除非在枚举声明本身中.与类类似,当你定义一个不带参数的枚举常量时,实际上是调用了编译器生成的默认构造函数.例如

Enum types can have constructors, provided that their access level is either private or default (package-private). You can not directly call these constructors, except in the enum declaration itself. Similar to classes, when you define an enum constant without parameters, you actually call the default constructor generated by the compiler. E.g.

public enum King {
    ELVIS
}

相当于

public enum King {
    ELVIS() // the compiler will happily accept this
}

就像在类中一样,如果你定义了一个显式构造函数,编译器不会插入一个默认构造函数,所以这不会编译:

And just like in classes, if you define an explicit constructor, the compiler will not insert a default constructor, so this will not compile:

public enum King {
    ELVIS, // error, default constructor is not defined
    MICHAEL_JACKSON(true)
    ;
    private boolean kingOfPop;
    King(boolean kingOfPop){this.kingOfPop = kingOfPop;}
}

这是关于枚举的一个很好的参考解释构造函数问题.

This is a pretty good reference on enums that also explains the constructor issues.

枚举是常量,因此是不可变的.然而,他们可以定义可以有状态的字段.这是一种糟糕的做法,因为开发人员希望枚举及其关联的值是常量,但是您仍然可以使用 getter 和 setter 在枚举中定义非 final 字段.

Enums are constants and are immutable as such. They can however define fields, that can have state. This is an awful practice, because developers will expect enums and their associated values to be constants, but you can still define a non-final field in an enum with getters and setters.

这是合法的java代码:

This is legal java code:

public enum Color {
    RED("FF0000"),
    GREEN("00FF00"),
    BLUE("0000FF");
    private String code;
    public String getCode(){return code;}
    public void setCode(String code){this.code = code;}
    private Color(String code){this.code = code;}
}

但它启用了这样的恶意代码:

But it enables evil code like this:

String oldBlue = Color.BLUE.getCode();
Color.BLUE.setCode(Color.RED.getCode());
Color.RED.setCode(oldBlue);

所以在 99.99% 的情况下:如果您的枚举中有字段,您应该将它们设为 final 并仅提供 getter.如果字段本身不是不可变的,请提供防御性副本:

So in 99.99 % of cases: if you have fields in your enums, you should make them final and provide getters only. If the fields are not immutable themselves, provide defensive copies:

public enum Band {
    THE_BEATLES("John","Paul","George","Ringo");
    private final List<String> members;
    public List<String> getMembers(){
        // defensive copy, because the original list is mutable
        return new ArrayList<String>(members);
    }
    private Band(String... members){
        this.members=Arrays.asList(members);
    }
}

解决方案

在您的情况下,它非常简单:您只需要一个字符串类型(不可变)的字段,因此在构造函数中初始化它并提供一个 getter 是完全可以的:

Solution

In your case it's very simple: you just need a single field of type string (immutable), so initializing it in the constructor and providing a getter is perfectly ok:

public enum Checker {

    EMPTY ("Empty"),
    RED ("Red"),
    YELLOW ("Yellow");

    private final String value;

    private Checker(final String value) {
        this.value = value;
    }

    public String getValue() { return value; }
}

这篇关于如何定义枚举项的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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