我有一个简单的枚举,像这样
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
};
现在给出了第一个枚举,第二个枚举是一种扩展。这可以使用扩展或类似方式实现吗?
我想实现通过相同(ID ==类型代码(的链接自动维护/检查。
一个想法是将 int typeCode 替换为包含 TypeId 的元素。
问题:
- 这是一个好/坏主意吗?
- 有没有更好的方法将这两个阶级结合起来?
- 将"扩展"定义为枚举是否好?(或者更确切地说是一个静态的最终数组?
您无法扩展枚举,但组合可以实现类似的结果。
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。 如果现有 API 是:
public TypeId someApi(int i) { .... }
public void myApi(DataType dt) { ... you prefer to use DataType ... }
然后,您现在有一种自然的方式来调用 myApi,如下所示:
myApi(DataType.ofType(someApi(5)));
方法是让两个枚举都实现一个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
枚举。
事实上,ID
(或 typeCode
( 只不过是枚举的隐式ordinal()
的显式等价物。
这意味着您可以轻松确保两个枚举中的值数量相同。如果它们不同,则意味着枚举不连贯。您可以简单地在确定要加载的另一个类中添加一个静态块(例如,如果相关,则包含main
static {
if (DataType.values().length != TypeID.values().length) {
throw new Error("Different lengths");
}
}
此外,如果要保留显式 ID,还可以确保它等于序号:
enum TypeID {
...
private TypeID (int id) {
ID = id;
if (id != ordinal()) throw new Error("ID out of sequence");
}
}
这样,您可以确保两个枚举都具有一致的 ID。