在 Effective Java,第 2 版中,Joshua Bloch 开发了“可扩展枚举模式”(第 34 项)。由于枚举不能被子类化,他建议通过让每个枚举实现一个通用类型(即接口)来统一相关枚举的组。这允许枚举通过它们的统一类型名称来引用。这种解决方案的明显问题是类型安全性受到了一定程度的损害,因为至少理论上可以通过简单地创建一个实现统一接口的类来替换任何非枚举对象来替换枚举。
为了解决这个问题,提出了一种解决方案。这是书中使用枚举的方法声明。示例应用程序有两个枚举 (BasicOperation
和ExtendedOperation
),它们都实现了一个统一的类型接口,称为Operation
. 该方法旨在接受任何适当类型的枚举:
private static <T extends Enum<T> & Operation> void test(
Class<T> opset, double x, double y) {
:
:
}
这样做的原因是泛型方法类型参数确保作为函数的第一个参数提供的类文字既是枚举类型又是操作类型。
这是我正在使用的枚举中的一些代码。这个枚举是一组枚举中的一个,我用来描述我在应用程序中使用的几个数据库表中的任何一个数据库列的元数据。每个表都有自己的枚举来描述这些数据,并且它们都通过实现ColumnMetaData<T>
接口来统一(T
对应于数据库表的类)。
class Client extends DB { // Class for the Clients table
// MetaData for all the columns in Client
static enum Column implements ColumnMetaData<Client> {
CLIENT_ID (...
:
:
);
}
}
我想在我的应用程序中使用一个名为Datum
. 它旨在将数据库列的值与其列枚举保持在一起。
这是我的问题:
我不能在构造函数中使用泛型方法参数Datum
。我如何告诉编译器其中一个字段Datum
必须同时实现ColumnMetaData<table>
and Enum<table.Column>
?目前,我正在使用以下内容:
static class Datum {
private final Object val;
private final ColumnMetaData<? extends DB > col;
private Datum(Object val, ColumnMetaData<? extends DB> col) {
this.val = val;
this.col = col;
}
// assorted static factories here...
:
:
}
这有效,但该值不被识别为枚举类型,我想将关联的枚举常量与EnumSet
and一起使用EnumMap
。
有没有我没有看到的优雅解决方案?