使用标记接口在 Java 中实现伪枚举继承
Implementing Pseudo Enum Inheritance in Java using a Marker Interface
我正在使用 来实现伪枚举继承。
假设我定义标记 class 如下:
public interface FieldInterface
现在我有 5 个枚举 class 实现了这个接口。
enum Field1 implements FieldInterface
enum Field2 implements FieldInterface
enum Field3 implements FieldInterface
enum Field4 implements FieldInterface
enum Field5 implements FieldInterface
上面的 5 个枚举“字段”class 中的每一个都定义了与该字段类型相关的枚举列表。例如,枚举 Field1
可能定义枚举:Field1A, Field1B, Field1C
。 Enum Field2
可能定义枚举:Field2A, Field2B, Field2C
现在我需要将每个枚举的纯文本表示转换为相应的枚举(类似于调用 enum.valueOf(String)
)不知道 5 个枚举中的哪个 class 是字符串属于.
实现此目的的一种方法可能是通过 reflection
首先检索实现所述接口的所有 classes 的列表并遍历所有 5 个枚举 classes 直到找到一个匹配项。但是,我更愿意尽可能避免反射(主要是由于性能原因)。
还有哪些其他选项可以解决这个问题?
谢谢
Map> 的传统实现,具有处理多个枚举的小复杂性 类。静态最终地图实例在接口中定义并在所有枚举之间共享。
import java.util.HashMap;
import java.util.Map;
import java.util.stream.IntStream;
class Main {
public static void main(final String[] args) {
// Enum classes must be loaded
loadEnums();
System.out.println(X.get("FIELD1B"));
((X) () -> "FIELD1B").add(); // Attempt to pollute the map is blocked
System.out.println(X.get("FIELD1B"));
}
private static void loadEnums() {
IntStream.range(1, 10).mapToObj(n -> Main.class.getPackageName() + ".Main$Field" + n).forEach(Main::loadEnum);
}
private static void loadEnum(String name) {
try {
Class.forName(name);
} catch (ClassNotFoundException e) {
}
}
/**
* All enums implement this marker interface and therefore share access to a static map from the name of the enum to its value.
*/
interface X {
Map<String, X> map = new HashMap<>();
/**
* This shared method uses enum's name method to get enum's string representation.
*/
default void add() {
if (this instanceof Enum<?>) {
map.put(name(), this);
}
}
static X get(String key) {
return map.get(key);
}
/**
* This method is always overwritten by each enum because all enums have a name() method.
*/
String name();
}
enum Field1 implements X {
FIELD1A, FIELD1B, FIELD1C;
// We have to call add() to place each enum value in the shared map
Field1() {
add();
}
}
enum Field2 implements X {
FIELD2A, FIELD2B, FIELD2C;
Field2() {
add();
}
}
}
我正在使用
假设我定义标记 class 如下:
public interface FieldInterface
现在我有 5 个枚举 class 实现了这个接口。
enum Field1 implements FieldInterface
enum Field2 implements FieldInterface
enum Field3 implements FieldInterface
enum Field4 implements FieldInterface
enum Field5 implements FieldInterface
上面的 5 个枚举“字段”class 中的每一个都定义了与该字段类型相关的枚举列表。例如,枚举 Field1
可能定义枚举:Field1A, Field1B, Field1C
。 Enum Field2
可能定义枚举:Field2A, Field2B, Field2C
现在我需要将每个枚举的纯文本表示转换为相应的枚举(类似于调用 enum.valueOf(String)
)不知道 5 个枚举中的哪个 class 是字符串属于.
实现此目的的一种方法可能是通过 reflection
首先检索实现所述接口的所有 classes 的列表并遍历所有 5 个枚举 classes 直到找到一个匹配项。但是,我更愿意尽可能避免反射(主要是由于性能原因)。
还有哪些其他选项可以解决这个问题?
谢谢
Map
import java.util.HashMap;
import java.util.Map;
import java.util.stream.IntStream;
class Main {
public static void main(final String[] args) {
// Enum classes must be loaded
loadEnums();
System.out.println(X.get("FIELD1B"));
((X) () -> "FIELD1B").add(); // Attempt to pollute the map is blocked
System.out.println(X.get("FIELD1B"));
}
private static void loadEnums() {
IntStream.range(1, 10).mapToObj(n -> Main.class.getPackageName() + ".Main$Field" + n).forEach(Main::loadEnum);
}
private static void loadEnum(String name) {
try {
Class.forName(name);
} catch (ClassNotFoundException e) {
}
}
/**
* All enums implement this marker interface and therefore share access to a static map from the name of the enum to its value.
*/
interface X {
Map<String, X> map = new HashMap<>();
/**
* This shared method uses enum's name method to get enum's string representation.
*/
default void add() {
if (this instanceof Enum<?>) {
map.put(name(), this);
}
}
static X get(String key) {
return map.get(key);
}
/**
* This method is always overwritten by each enum because all enums have a name() method.
*/
String name();
}
enum Field1 implements X {
FIELD1A, FIELD1B, FIELD1C;
// We have to call add() to place each enum value in the shared map
Field1() {
add();
}
}
enum Field2 implements X {
FIELD2A, FIELD2B, FIELD2C;
Field2() {
add();
}
}
}