扩展枚举属性

时间:2018-02-28 13:20:20

标签: java enums

我有一个像这样的简单枚举

public enum TypeId {
    Unknown(0),
    I1(1),
    I2(2),
    I4(3),
    I8(4),
    Ui1(5),
    Ui2(6),
    Ui4(7) 
    // ...
    ;
    private final int ID;
    private TypeID (int id) { ID = id; }
    public int getID () { return ID;  }
    public static TypeID getTypeID(int id) { ... }
};

更复杂的一个,包含更多数据,但覆盖相同ID元素相关的相同元素。

public enum DataType {
    T_Null(0, "NULL", Types.NULL, 0, 0),
    T_Int8(1, "TINYINT", Types.TINYINT, 1, 4), 
    T_Int16(2, "SMALLINT", Types.SMALLINT, 2, 6), 
    T_Int32(3, "INTEGER", Types.INTEGER, 4, 11),
    T_Int64(4, "BIGINT", Types.BIGINT, 8, 20), 
    T_UInt8(5, "BYTE", Types.TINYINT, 1, 3), // 0 -> 255
    T_UInt16(6, "USHORT", Types.SMALLINT, 2, 5), // 0 -> 65535
    T_UInt32(7, "UINT", Types.INTEGER, 4, 10) // 0 -> 4294967295  
    // ...
    ; 
    private final int typeCode, sqlTypeCode, binSize, dispSize;
    private String typeName;

    private DataType(int typeCode, String typeName, int sqlTypeCode, int binSize, int dispSize) {
      this.typeCode = TypeCode;
      this.typeName = TypeName;
      this.sqlTypeCode = sqlTypeCode;
      this.binSize = binSize;
      this.dispSize = dispSize;
    }
    public String getName() { return typeName; }
    // other getters 
};

现在给出了第一个枚举,第二个是一种扩展。 这可以使用 extends 或类似的吗?

来实现

我想实现自动维护/检查通过相同(ID == typeCode)的链接。

一个想法是用TypeId包含Element替换int typeCode。

问题:

  • 这是好主意还是坏主意?
  • 是否有更好的方法将这两个班级结合在一起?
  • 定义"扩展名"是否合适?作为一个枚举? (或者说是静态的最终数组?)

3 个答案:

答案 0 :(得分:1)

最简单的方法是使两个枚举实现interface。显然,你仍然没有完整的安全检查,唯一性成为你的问题,但这是一个解决方案。

public interface HasId {
    int getID ();
}

public enum TypeID implements HasId{
    Unknown(0),
    I1(1),
    I2(2),
    I4(3),
    I8(4),
    Ui1(5),
    Ui2(6),
    Ui4(7)
    ;
    private final int ID;
    private TypeID (int id) { ID = id; }
    @Override
    public int getID () { return ID;  }
};

public enum DataType implements HasId{
    T_Null(0, "NULL", Types.NULL, 0, 0),
    T_Int8(1, "TINYINT", Types.TINYINT, 1, 4),
    T_Int16(2, "SMALLINT", Types.SMALLINT, 2, 6),
    T_Int32(3, "INTEGER", Types.INTEGER, 4, 11),
    T_Int64(4, "BIGINT", Types.BIGINT, 8, 20),
    T_UInt8(5, "BYTE", Types.TINYINT, 1, 3), // 0 -> 255
    T_UInt16(6, "USHORT", Types.SMALLINT, 2, 5), // 0 -> 65535
    T_UInt32(7, "UINT", Types.INTEGER, 4, 10) // 0 -> 4294967295  
    // ...
    ;
    private final int typeCode, sqlTypeCode, binSize, dispSize;
    private String typeName;

    private DataType(int typeCode, String typeName, int sqlTypeCode, int binSize, int dispSize) {
        this.typeCode = typeCode;
        this.typeName = typeName;
        this.sqlTypeCode = sqlTypeCode;
        this.binSize = binSize;
        this.dispSize = dispSize;
    }
    public String getName() { return typeName; }
    // other getters
    @Override
    public int getID () { return typeCode;  }
};

对于TypeId枚举的int,我可能会使用typeCode代替DataType

答案 1 :(得分:1)

实际上[UTab].[Iteration](resp。UPDATE [UTab] SET [ENum] = [__Tmp].[ENum], [Iteration] = N'Iteration#1' --SELECT __Tmp.ENum, __Tmp.Link, __Tmp.LSPEC, __Tmp.ADT, __Tmp.SDT, __Tmp.DT, __Tmp.Idx FROM [UTab] AS up INNER JOIN [__Tmp] ON [up].[MRN] = [__Tmp].[Link] AND [up].[SIDate] = [__Tmp].[DT] AND [up].[LSPEC] = [__Tmp].[LSPEC] WHERE __Tmp.Idx = 1; )只不过是枚举的隐式ID的明确等价物。

这意味着您可以轻松确保在两个枚举中具有相同数量的值。如果它们不同则意味着枚举不连贯。您可以在另一个确定要加载的类中添加一个静态块(例如,如果它是相关的,则包含typeCode的那个):

ordinal()

如果你想保留显式ID,你还可以确保它等于序数:

main

通过这种方式,您可以确保两个枚举都具有连贯的ID。

答案 2 :(得分:1)

您无法扩展枚举,但合成会获得类似的结果。

public enum DataType {
    T_Null(TypeId.Unknown, "NULL", Types.NULL, 0, 0),
    T_Int8(TypeId.I1, "TINYINT", Types.TINYINT, 1, 4), 
    T_Int16(TypeId.I2, "SMALLINT", Types.SMALLINT, 2, 6), 
    T_Int32(TypeId.I4, "INTEGER", Types.INTEGER, 4, 11),
    T_Int64(TypeId.I8, "BIGINT", Types.BIGINT, 8, 20), 
    T_UInt8(TypeId.Ui1, "BYTE", Types.TINYINT, 1, 3), // 0 -> 255
    T_UInt16(TypeId.Ui2, "USHORT", Types.SMALLINT, 2, 5), // 0 -> 65535
    T_UInt32(TypeId.Ui4, "UINT", Types.INTEGER, 4, 10) // 0 -> 4294967295  
    ; 
    private final TypeId typeId;
    private final int sqlTypeCode, binSize, dispSize;
    private final String typeName;

    private DataType(TypeId typeId, String typeName, int sqlTypeCode, int binSize, int dispSize) {
      this.typeId = typeId;
      this.typeName = typeName;
      this.sqlTypeCode = sqlTypeCode;
      this.binSize = binSize;
      this.dispSize = dispSize;
    }
    public String getName() { return typeName; }
    // other getters 

    public static DataType ofType(TypeId typeId) {
        for (DataType dt : values())
            if (dt.typeId == typeId)
                return dt;
        return T_Null;
    }

};

据推测,您有动力更自然地使用现有的API。如果现有的apis是:

public TypeId someApi(int i) {  ....  }

public void myApi(DataType dt) { ... you prefer to use DataType ... }

然后你现在有一种自然的方式来调用myApi,如下所示:

myApi(DataType.ofType(someApi(5)));