I am trying to write generic Json deserializer as below,
public static <T> BiFunction<String, Class<T>, T> jsonDeSerializer() {
return (o, c) -> {
try {
return mapper.readValue(o, c);
} catch (IOException e) {
logger.error("json.parse.error object.type={}", o.getClass().getSimpleName(), e);
throw new JsonProcessingEx(e);
}
};
}
When trying to call, I am getting
error: incompatible types: Class<MLAdhocResponseVO> cannot be converted to Class<Object>
MLAdhocResponseVO response = JsonUtils.jsonDeSerializer().apply("{}", MLAdhocResponseVO.class);
All I want to to write a BiFunction which returns Object based on provided class without need of any typecasting.
When you call
JsonUtils.jsonDeSerializer().apply("{}", MLAdhocResponseVO.class);
jsonDeSerializer()
's generic type argument is Object
(this and this can shed more light), not MLAdhocResponseVO
as you seem to expect.
The quick fix is to add a type witness to the call, to tell the compiler what your intended type argument for the method is:
MLAdhocResponseVO response = JsonUtils.<MLAdhocResponseVO>jsonDeSerializer()
.apply("{}", MLAdhocResponseVO.class);
Alternatively, you can give the compiler a target type by declaring a typed BiFunction
variable:
BiFunction<String, Class<MLAdhocResponseVO>, MLAdhocResponseVO>
function = jsonDeSerializer();
MLAdhocResponseVO response = function.apply("{}", MLAdhocResponseVO.class);
If you want to avoid this altogether, then your method may be better designed with an actual parameter of the generic type, which will assist the compiler's type inference:
public static <T> Function<String, T> jsonDeSerializer(Class<T> c) {
return (o) -> {
try {
return mapper.readValue(o, c);
} catch (IOException e) {
logger.error("json.parse.error object.type={}",
o.getClass().getSimpleName(), e);
throw new JsonProcessingEx();
}
};
}
This way, your code compiles without needing a type witness:
MLAdhocResponseVO response = JsonUtils.jsonDeSerializer(MLAdhocResponseVO.class)
.apply("{}");
And even this standalone expression is correctly typed:
JsonUtils.jsonDeSerializer(MLAdhocResponseVO.class)
.apply("{}");