Java 高级 Enum 带有抽象方法并用于分支

Hor*_*ice 4 java oop enums

我是 Java 新手,在我的组织中遇到了一些高级 Enum 代码。我熟悉枚举定义如下:public enum someList { VALUE1, VALUE2, ..}

但是在我遇到的高级枚举中,似乎还有更多的事情发生..

/**
 * Defines ways to compare records in {@link ApplicationStatus} to see if they
 * are the same.
 */
public enum SourceStatusComparisonType
{
    CONTEXT_KEY
    {
        @Override
        public boolean compareKeys(SourceStatus source, ApplicationStatus status)
        {
            return source.getContextKey() == status.getSourceContextId();
        }
    },
    DATE
    {
        @Override
        public boolean compareKeys(SourceStatus source, ApplicationStatus status)
        {
            return source.getCobDate().equals(status.getCobDate());
        }
    };

    public abstract boolean compareKeys(SourceStatus source,
            ApplicationStatus status);
}
Run Code Online (Sandbox Code Playgroud)

有人可以启发我了解被覆盖和重载的抽象方法发生了什么。我不明白上面发生了什么。有人告诉我,这被用来从使用它的代码中抽象出 if/else 块。但我不确定我是否理解。

先感谢您。

Roh*_*ain 5

JLS §8.9 中指定的那样,每个枚举常量都可以选择跟在一个类主体之后

枚举常量的可选类主体隐式定义了一个匿名类声明(第 15.9.5 节),该声明扩展了直接封闭的枚举类型。类主体由匿名类的通常规则管理;特别是它不能包含任何构造函数。

所以,这就像创建一个抽象类SourceStatusComparisonType,使用抽象方法 - compareKeys()。您创建该类的 2 个实例:

CONTEXT_KEY = new SourceStatusComparisonType() {
        @Override
        public void compareKeys() { .. }
    };

DATE = new SourceStatusComparisonType() {
        @Override
        public void compareKeys() { .. }
    };
Run Code Online (Sandbox Code Playgroud)

并覆盖每个实例的抽象方法。如果没有该方法的实现,就不能拥有任何实例。

类似地,所有枚举常量必须在其各自的匿名类主体中提供抽象方法的实现。否则,您不能将该方法作为抽象方法。您必须提供一个主体,默认情况下将用于枚举常量,不提供该方法实现:

public enum SourceStatusComparisonType
{
    CONTEXT_KEY
    {
        @Override
        public boolean compareKeys(SourceStatus source, ApplicationStatus status)
        {
            return source.getContextKey() == status.getSourceContextId();
        }
    },
    DATE
    {
        @Override
        public boolean compareKeys(SourceStatus source, ApplicationStatus status)
        {
            return source.getCobDate().equals(status.getCobDate());
        }
    },
    DEFAULT;

    public boolean compareKeys(SourceStatus source,
            ApplicationStatus status) {
//        return somedefaultvalue;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,对于前2个常量,当你调用compareKeys方法时,会用到它们的具体实现,而for DEFAULT,会用到外面定义的方法。