Java 枚举关联



我正在尝试创建一个场景,其中通过enum class A中的枚举常量将子enum class B和包含自己的常量enum class C相关联。enum class B 中的常量和 enum class C 组中的常量是 enum class D 中的常量子集。以下是我想要实现的基本目标:

enum A {
    CONST_1 ("const_1", B), // B is the associated enum
    CONST_2 ("const_2", C); // C in the associated enum
    private final String strVal;
    private final Enum associatedEnum;
    private A (String strVal, Enum associatedEnum) {
        this.strVal = strVal;
        this.associatedEnum = associatedEnum;
    }
    public Enum getAssociatedEnum() {
        return this.associatedEnum;
    }
    public String toString() {
        return this.strVal;
    }       
    // Associated Enum contained subset of grouped constants
    enum B {
        CONST_3 (D.CONST_7.toString()),
        CONST_4 (D.CONST_8.toString()); 
        private final String strVal;
        private B (String strVal) {
            this.strVal = strVal;
        }
        public String toString() {
            return this.strVal;
        }       
    }
    // Associated Enum contained subset of grouped constants
    enum C {
        CONST_5 (D.CONST_9.toString()),
        CONST_6 (D.CONST_10.toString()); 
        private final String strVal;
        private C (String strVal) {
            this.strVal = strVal;
        }
        public String toString() {
            return this.strVal;
        }              
    }
}
// Separate Enum containing all ungrouped constants
enum D {
    CONST_7 ("const_7"),
    CONST_8 ("const_8");
    CONST_9 ("const_9"),
    CONST_10 ("const_10");
    private final String strVal;
    private D (String strVal) {
        this.strVal = strVal;
    }
    public String toString() {
        return this.strVal;
    }    
}

显然,这种语法在 OOTB 中不起作用,因为您无法以这种方式在 Java 中传递类。但是谁能提出一种可以实现这一目标的方法?

我希望使用它来验证客户端应用程序中的静态结构化分组。

这应该有希望做你想要的。我包含一个示例用法,它将列出子枚举类型值。

package a.b.c;

public class EnumsTest {
  public enum A {
    A1( B.class ),
    A2( C.class );
    private final Class<? extends Enum<?>> enumClazz;
    A( final Class<? extends Enum<?>> enumClazz  ) {
      this.enumClazz = enumClazz;
    }
    public Enum<?>[] getSubEnumConstants() {
      return enumClazz.getEnumConstants();
    }
   /**
    * @param value
    * @return Never null
    * @throws IllegalArgumentException To be consistent with Enum.valueOf()
    */
   public <T> Enum<?> valueOfSubEnum( final String value ) throws IllegalArgumentException {
     for( Enum<?> enumInstance : getSubEnumConstants() ) {
       if( enumInstance.name().equals( value ) ) {
         return enumInstance;
       }
     }
     throw new IllegalArgumentException( "valueOf for " + enumClazz.getName() + " could not be resoled with the value of " + value );
   }
  }
  public enum B {
    B1,
    B2;
  }
  public enum C {
    C1,
    C2;
  }
  public static void main( String[] args ) {
    for( A a : A.values() ) {
      for( Enum<?> enumInstance : a.getSubEnumConstants() ) {
        System.out.println( a.name() + ":" +  enumInstance.name() );  
      }
    }
    Enum<?> valueOfSubEnum = A.A1.valueOfSubEnum( "B2" );
    System.out.println( valueOfSubEnum.name() );
  }
}

注: 如果要将子类型锁定到特定集,则可以使它们实现接口。

不能使用构造函数private B (String strVal, Enum associatedEnum)声明enum A。你可以在彼此内部声明其他枚举,但不能这样。

这对我有用,但我可能错过了您要实现的目标:

public enum A {
  A1(B.B1),
  A2(C.C2);
  private final Enum<?> e;
  private A(Enum<?> e) {
    this.e = e;
  }
  static enum B {
    B1,
    B2;
  }
  static enum C {
    C1(D.D1.getId()),
    C2(D.D2.getId());
    private String id;
    private C(String id) {
      this.id = id;
    }
  }
}
enum D {
  D1("abc"),
  D2("def");
  private final String id;
  private D(String id) {
    this.id = id;
  }
  public String getId() {
    return id;
  }
}

最新更新