The problem
We are save configuration elements to Dynamodb: the key is the configuration name, the value is the JSON string.
Recently I am trying to refactor the code to make the service code much shorter and easier to read. But I made one mistake - related with Java Type erasure.
The following code tries to read configuration: its value is a Map. I want to create one generic method that can read different Map.
The Solution
We have to specify class type like below:
Read More
Jackson Essentials - the JSON Libaray
Using Jackson JSON View to Protect Mass Assignment Vulnerabilities
Merge JSON Objects: Jackson + BeanUtils.copyProperties
Jackson Generic Type + Java Type Erasure
Jackson Date Serialize + Deserialize
Apache Commons TypeLiteral
Google Guice TypeLiteral
Effects of Type Erasure and Bridge Methods
We are save configuration elements to Dynamodb: the key is the configuration name, the value is the JSON string.
Recently I am trying to refactor the code to make the service code much shorter and easier to read. But I made one mistake - related with Java Type erasure.
The following code tries to read configuration: its value is a Map
@Nonnull private <T> Map<String, T> getMapConfig(final String configName) { final ConfigElement c = configDao.getConfigByName(configName); Map<String, T> resultMap = null; if (c != null) { String json = c.getValue(); resultMap = objectMapper.readValue(json, new TypeReference<Map<String, T>>() {}); } if (resultMap == null) { resultMap = new HashMap<>(); } return resultMap; } private <T> T convertMapValue(final String json) { return objectMapper.readValue(json, new TypeReference<T>(){}); }But this doesn't work: because of type erasure, T is just a type variable, at runtime, Java can't get the real value of the type.
The Solution
We have to specify class type like below:
@Nonnull private <T> Map<String, T> getMapConfig(final String configName, final Class<T> classType) { final ConfigElement c = configDao.getConfigByName(configName); Map<String, T> resultMap = null; if (c != null) { String json = c.getValue(); final MapType mapType = TypeFactory.defaultInstance().constructMapType(Map.class, String.class, classType); resultMap = objectMapper.readValue(json, mapType); } if (resultMap == null) { resultMap = new HashMap<>(); } return resultMap; } private <T> T convertMapValue(final String json,final Class<T> valueType) { return objectMapper.readValue(json, valueType); }One related stuff I found is that in eclipse you can change Eclipse's Warning settings so that if Eclipse will show warnings if some parameter are not used: Change -> Window/Preferences /Java/Compiler/ErrorsWarnings -> Unnecessary Code > Value of parameter is not used to warning.
Read More
Jackson Essentials - the JSON Libaray
Using Jackson JSON View to Protect Mass Assignment Vulnerabilities
Merge JSON Objects: Jackson + BeanUtils.copyProperties
Jackson Generic Type + Java Type Erasure
Jackson Date Serialize + Deserialize
Apache Commons TypeLiteral
Google Guice TypeLiteral
Effects of Type Erasure and Bridge Methods