代码之家  ›  专栏  ›  技术社区  ›  jon hanson

定义外无法访问Java枚举值字段

  •  0
  • jon hanson  · 技术社区  · 6 年前

    在下面的代码中 Colours 枚举 GREEN 值在枚举定义之外不可访问:

    public class Test {
    
        enum Colours {
            RED,
            GREEN {
                public static final int hex = 0x00ff00;
                public final int hex2 = 0x00ff00;  // Try it without static, just in case...
    
                void f() {
                    System.out.println(hex);    // OK
                    System.out.println(hex2);   // OK
                }
            },
            BLUE
        }
    
        public static void main(String[] args) {
            System.out.println(Colours.GREEN.hex);      // COMPILE ERROR
            System.out.println(Colours.GREEN.hex2);     // COMPILE ERROR
        }
    }
    

    违规行会导致以下编译器错误:

    Error:(38, 41) java: cannot find symbol
      symbol:   variable hex
      location: variable GREEN of type Test.Colours
    

    你知道为什么这样不行吗?我认为Java标准禁止它,但为什么呢?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Karol Dowbecki    6 年前

    根据 JLS §8.9.1. Enum Constants 一个 enum 常量体由适用于匿名类的规则控制,这些规则限制字段和方法的可访问性:

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

        2
  •  1
  •   BackSlash    6 年前
    enum Colours {
        RED,
        GREEN {
            public static final int hex = 0x00ff00;
            public final int hex2 = 0x00ff00;  // Try it without static, just in case...
    
            void f() {
                System.out.println(hex);    // OK
                System.out.println(hex2);   // OK
            }
        },
        BLUE
    }
    

    这里,两个 RED , GREEN BLUE 属于类型 Colours ,它不知道 hex , hex2 f ,这就是为什么您的代码无法编译。

    您可以在枚举定义中移动它们:

    enum Colours {
        RED(0xff0000, 0xff0000),
        GREEN(0x00ff00, 0x00ff00),
        BLUE(0x0000ff, 0x0000ff);
    
        final int hex;
        final int hex2; 
    
        Colours(int hex, int hex2) {
            this.hex = hex;
            this.hex2 = hex2;
        }
    
        void f() {
            System.out.println(hex);    // OK
            System.out.println(hex2);   // OK
        }
    }
    

    所有这些都将通过这种方式编译:

    System.out.println(Colours.GREEN.hex);
    System.out.println(Colours.GREEN.hex2);
    Colours.GREEN.f();