在遍历JSON文档中的值时,我使用了以下方法:
protected static <T> T getValueAs(Object untypedValue, Class<T> expectedType) {
if (expectedType.isAssignableFrom(untypedValue.getClass())) {
return (T) untypedValue;
}
throw new RuntimeException("Failed");
}
在大多数情况下,它工作得很好,但是当调用如下所示时会失败(抛出异常):
getValueAs((Long) 1L, Double.class);
我知道这是因为Long
和Double
不兼容。
Double d = (Long) 1L;
导致error: incompatible types: Long cannot be converted to Double
。
我想知道我的方法是否可以工作,即使在这种情况下- Long
值被转换为Double
。
我见过来自Apache的isAssignable(),但我认为它只会使条件正常工作,并且在转换过程中会失败--我期望类型为Double
,值为Long
类型(而不是原语)。
发布于 2022-04-28 20:47:19
这种过载的方法是否可以接受?
Double n = getValueAs(1L, Number.class, Number::doubleValue);
protected static <P,T> T getValueAs(Object untypedValue, Class<P> expectedType, Function<P, T> f) {
if (expectedType.isAssignableFrom(untypedValue.getClass())) {
return f.apply((P)untypedValue);
}
throw new RuntimeException("Failed");
}
发布于 2022-04-28 19:53:01
您可能别无选择,只能执行转换。但是,由于您的方法不知道如何转换未知类的值,所以可以将其留给调用方负责:
protected static <T> T getValueAs(Object untypedValue, Class<T> expectedType) {
return getValueAs(untypedValue, expectedType, null);
}
protected static <T> T getValueAs(Object untypedValue, Class<T> expectedType,
Function<Object, T> converter) {
if (expectedType.isAssignableFrom(untypedValue.getClass())) {
//use Class.cast to skip unchecked cast warning
return expectedType.cast(untypedValue);
} else if (null != converter) {
return converter.apply(untypedValue);
}
throw new RuntimeException("Failed");
}
调用可能是这样的:
getValueAs(1L, Double.class, v -> ((Number) v).doubleValue());
当然,您可以在getValueAs()
中添加一些您的方法支持的转换,特别是对于最常见的场景;因此,您的调用方不必为此编写转换器。
https://stackoverflow.com/questions/72049320
复制相似问题