首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >枚举常值加法类

枚举常值加法类
EN

Stack Overflow用户
提问于 2019-02-23 19:25:04
回答 1查看 83关注 0票数 2

在枚举的常值声明中,在类主体中添加onymous (而不是匿名)类方法的用法是什么?

代码语言:javascript
复制
public enum Status {
    SUCCESS("SUCCESS"){},FAILED("FAILED"){  
         class Test { 
               public void test() {
                  System.out.println("test");
               }
         }
    };
    private String code;

    Status(String code) {
        this.code = code;
    }

如何访问/执行这样的方法?我找到了匿名类示例,这是不推荐的

作为一项建议,让您的enum实现您的接口,使代码更加可读性。

我没有在JLS的Enum常量部分找到用法。

枚举常量的可选类体隐式定义了一个匿名类声明(§15.9.5),它扩展了立即包围枚举类型。类主体是,受匿名类的常规规则控制;特别是它不能包含任何构造函数。 只有在这些类体中声明的实例方法覆盖封闭枚举类型中的可访问方法时,才能在封闭枚举类型之外调用它们。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-23 21:17:21

TL博士很难想象现实世界中定义枚举常量内部类的情况是合理的。

让我们从你的代码示例开始。

代码语言:javascript
复制
public enum Status {
    SUCCESS("SUCCESS") {

    },
    FAILED("FAILED") {  
        class Test { 
            public void test() {
                System.out.println("test");
            }
        }
    };
    private String code;

    Status(String code) {
        this.code = code;
    }
}

由于FAILED是一个带有主体的枚举值,它将成为Status枚举类的匿名子类。Test是在这个匿名类中定义的。由于其封闭类的匿名性,无法从FAILED之外表示其名称。这肯定不是Status.FAILED.Test

因此,TestFAILED中主要是有用的(如果FAILED的实现足够复杂到需要一个内部类),一般来说,我更喜欢枚举常量,而不是变得那么复杂,但这是一个风格问题。

Test外部访问FAILED只能通过Test扩展/实现的超类或接口来实现,并且只能访问通过该超类或接口公开的方法。

一个(人为的)示例显示FAILED内部和外部的用法,可能是:

代码语言:javascript
复制
public class StatusTest {

    enum Status {
        FAILED{  
            class Test implements Runnable { 
                private String text = "Test " + System.currentTimeMillis();
                @Override
                public void run() {
                    System.out.println(text);
                }
            }
            @Override
            public Runnable getRunner() {
                return new Test();
            }
            @Override
            public void message() {
                getRunner().run();
            }
        };
        public abstract void message();
        public abstract Runnable getRunner();
    }

    public static void main(String[] args) {
        Status status = Status.FAILED;
        status.message();
        Runnable runner = status.getRunner();
        runner.run();
    }
}

(后加)

当然,在这个例子中,Runnable没有理由获得一个类名。我通常使用命名的内部类,而不是匿名类,只有当它是

  • 用于多个地方或
  • 太复杂了,它会使这个封闭的方法无法读懂。

在引入匿名类和命名内部类时,这总是相同的决定。对于枚举,给内部类命名的理由更少,因为这个名称在外部是不可用的。所以,如果我看到上面这样的代码,我会重构它以使用一个匿名类:

代码语言:javascript
复制
public class StatusTest {

    enum Status {
        FAILED { 
            @Override
            public Runnable getRunner() {
                return new Runnable() { 
                    private String text = "Test " + System.currentTimeMillis();
                    @Override
                    public void run() {
                        System.out.println(text);
                    }
                };
            }
            @Override
            public void message() {
                getRunner().run();
            }
        };
        public abstract void message();
        public abstract Runnable getRunner();
    }

    public static void main(String[] args) {
        Status status = Status.FAILED;
        status.message();
        Runnable runner = status.getRunner();
        runner.run();
    }
}

在这两种情况下,内部类本身对外部代码都是不可见的,只在枚举常量中可见,而且如果枚举常量的实现变得如此复杂以至于需要命名的内部类,我肯定会重构它,例如将复杂性委托给一些普通的顶级类。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54845306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档