[英]What is a good data structure for representing a field that is more complex than an enum, but not quite a class?
[英]What is a good extensible way to check if a string is a value of more than one Enum Type
假设我有一堆逻辑上不同的 Java 枚举,它们不能合并在一起,因为某些先前的操作依赖于每个独立的枚举。
enum Enum1 {
ENUM1VAL1,
ENUM1VAL2
}
enum Enum2 {
ENUM2VAL1,
ENUM2VAL2
}
void existingOperationOnEnum1(Enum1 enum1);
void existingOperationOnEnum2(Enum2 enum2);
现在假设我希望定义一个新操作来检查字符串是否可以转换为这些枚举中的任何一个
void isValidStringConversionForEnums(final String input) {
ENUM1.valueOf(input); // Throws IllegalArgumentException if conversion not possible
ENUM2.valueOf(input); // Throws IllegalArgumentException if conversion not possible
}
所以这很棒,但它不可扩展。 业务逻辑是这样的,我们可以在未来创建新的枚举(使用它自己的一组特定于枚举的操作),但是每次添加新枚举时都需要更新 isValidStringConversionForEnums,程序员可能很容易忘记这一点。
所以我的问题是我将如何修改 isValidStringConversionForEnums 以便它适用于未来的扩展。
我认为的一种方法是创建一个接口 EnumBase,让 Enums 扩展它,然后使用反射来获取所有 Enum 实现,但我不希望在运行时使用反射,除非我必须这样做。
是否有另一种方法可以编写它,以便我添加一个新的枚举并以某种方式 isValidStringConversionForEnums 处理该新枚举。
您在这里有两个独立的问题:
这两个问题完全不相关。 所以,你分别解决它们。
Class<? extends Enum>
Class<? extends Enum>
可能是你最好的选择。
enum Test1 {
FOO, BAR;
}
enum Test2 {
FOO, BAZ;
}
public static void isValidStringConversionForEnums(String in, Class<? extends Enum>... enumTypes) {
for (var enumType : enumTypes) {
for (var c : enumType.getEnumConstants()) {
if (c.name().equals(in)) return true;
}
}
return false;
}
这不是特别有效 - 但你明白了要点。 您可以预先制作一个包含每个有效值的 HashSet,然后它只是一个.containsKey()
调用,使用上面的代码代替一次性的“init”,例如制作该 HashSet。 如果您确实需要枚举常量,请制作一个Map<String, List<? extends Enum<?>>
改为Map<String, List<? extends Enum<?>>
。 computeIfAbsent
是一种在单行中动态创建这些列表的好方法。
java 类加载器抽象系统根本没有“给我一个 jar 中所有文件的列表”或“给我一个所有类的列表”。 一些库似乎提供了这些功能,但它们并不总是有效,因此您可能不想使用这些功能。
JVM本身也使用这个问题的标准解决方案是'SPI' - 如果你不使用它,它就会被包含在module-info.java中(你可能不应该使用它,这有点棘手) ,有ServiceLoader
。 要制作服务文件,您可以使用注释处理器,我认为周围有一些可以自动化它。
然后流程很简单,要创建一个新的枚举,在上面粘贴一个@ProviderFor(Something.class)
,其中Something.class
是您设计的一些标记接口。
请注意,想要扫描整个类路径上的所有枚举是非常糟糕的。 java内部使用了各种各样的枚举,如果其中一个恰好有一个等于你的字符串之一的值怎么办? 这并不会突然使它成为一个有效的字符串。 不,只有你明确标记为适用于这个问题的枚举,有资格,这个,你需要做一些事情来标记它们。 要么带有注释,要么明确地写出完整列表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.