[我正在尝试编写一个实用程序类,该实用程序类可以包含String
和Class<?>
,并返回实际上是该Object
的类型化实例的String
。
例如,如果我有字符串"FALSE"
和类"java.lang.Boolean"
,我想返回键入的Boolean.FALSE
。等其他类,例如String,Long,Int,Enum等。
我想以一种在添加新类型时不需要太多重写的方式来执行此操作。目前,我有一个签名为Object getTypedValue(Class<?> clazz, String value);
的方法。
[从这里,我以为我可以使用Map<Class<?>, Function<String, Object>>
。对于像String和Boolean这样的情况,这很好用,但是对于Enum,我也需要类名。因此,映射变为Map<Class<?>, BiFunction<String, Class<?>, Object>>
。
但是大多数方法不需要Class参数。还发现了一个新的FunctionalInterface,如:
@FunctionalInterface
public interface OptionalClassFunction<T, CLAZZ, R> {
R apply(T t, CLAZZ... clazz);
}
当我通过仅以T作为lambda的方法时,似乎不起作用。
例如
ImmutableMap.of(
Boolean.class, Util::toBoolean
)
private Boolean toBoolean(String value);
不起作用。
关于如何处理的任何建议:
Map<Class<?>, WhateverFunction<String, MAYBE_A_CLASS, Object>>
吗?
示例方法为:
public static Boolean toBoolean(String value) {
// derive bool
}
public static Enum toEnum(String value, Class<?> fieldType) {
// derive enum
}
为什么您需要枚举的类名?
例如DayOfWeek
是一个DayOfWeek
,并且与其他所有enum
类一样,它具有enum
方法,因此只需注册以下内容:
valueOf(String name)
[如果您不喜欢valueOf(String name)
方法,例如因为它区分大小写,并且您的DayOfWeek.class, DayOfWeek::valueOf
方法更好,所以请编写一个辅助方法来封装它,例如
valueOf
然后您使用以下方式注册:
toEnum
助手很好,但是您实际上并不需要它:
public static <T extends Enum<T>> Function<String, T> getEnumParser(Class<T> type) {
return s -> toEnum(s, type);
}
public static <T extends Enum<T>> T toEnum(String value, Class<T> type) {
for (T constant : type.getEnumConstants())
if (constant.name().equalsIgnoreCase(value))
return constant;
throw new IllegalArgumentException("Unknown constant for enum " + type.getName() + ": \"" + value + "\"");
}
除非与DayOfWeek.class, Util.getEnumParser(DayOfWeek.class)
一起使用可能会使编译器感到困惑。该帮助程序解决了潜在的编译器推断问题。
关于如何处理的任何建议:
DayOfWeek.class, s -> Util.toEnum(s, DayOfWeek.class)
总是将其设为ImmutableMap.of(...)
,而只需忽略Map<Class<?>, WhateverFunction<String, MAYBE_A_CLASS, Object>>
参数:
BiFunction
由于地图的用户将不知道是否需要Class<?>
参数,因此它必须始终传递值,例如
Map<Class<?>, BiFunction<String, Class<?>, Object>> map = Map.of(
Boolean.class, (s,t) -> Util.toBoolean(s),
Enum.class, Util::toEnum
);
简体。通常在Class<?>
调用后检查是否为null。
当然,这也不起作用,因为呼叫者认为类型是Class<?> type = ...
String value = ...
Object obj = map.get(type).apply(value, type);
,因此,如果调用方执行get()
,查找将失败。现在,调用者所需的逻辑突然变得复杂。
解决方案是将DayOfWeek
逻辑封装在一个辅助方法中,因此您可以将type = DayOfWeek.class
替换为get-apply
来进行地图查找,但是如果这样做,您可能还直接构建了对枚举,绕过地图,并以DayOfWeek.class
离开地图。