Reputation: 51311
I want a method that extracts the data from a JSON-object parsed before as the correct type. The JSONObject (rawdata) extends Map, so it looks like this:
private <Type> Type getValue(String key, Type def)
{
if (!rawdata.containsKey(key)) return def;
if (!(rawdata.get(key) instanceof Type)) return def;
return (Type) rawdata.get(key);
}
The instanceof
obviously generates a compile-time-error. The parameter def
is the default-value, returned if the key is not available or has the wrong type. But def
can also be null, so def.getClass()
isn't working.
Any ideas how I can check the content of the Map-entry for the correct type?
Upvotes: 1
Views: 4631
Reputation: 27677
Or you could use the Typesafe Heterogeneous Container (THC) pattern from "Effective Java Second Edition" book by Joshua Bloch.
Basically, store the item's Class in the map when inserting. When retrieving you'll know the type is the same.
Map<Class, Map<String, Object>> rawData = ...
Upvotes: 0
Reputation: 40693
You just need to check for nulls (a null will count as any type, if this is undesired behaviour then you will also need to pass in the desired class).
private <T> T getValue(String key, T def)
{
if (!rawdata.containsKey(key)) return def;
Object value = rawdata.get(key);
if (def == null) return (T) value;
// note that the above is inherently unsafe as we cannot
// guarantee that value is of type T
// this if statement is the same as "value instanceOf Type"
// is type safe, but not null safe
if (def.getClass().isAssignableFrom(value.getClass())) {
return (T) value;
} else {
return def;
}
}
A safer method signature would be:
private <T> T getValue(String key, T defaultValue, Class<T> defaultClass)
This way we can safely check the types match even when the default is null.
Upvotes: 2
Reputation: 7110
Your best bet is probably to accept a Class
object for the return type in the case when no default value is given. You can just overload the function like:
private <T> T getValue(String key, Type defaultValue);
private <T> T getValue(String key, Class<T> type);
Upvotes: 1
Reputation: 346300
Due to type erasure, the only way to handle the case where the default value can be null is to have the method require an additional parmeter of type Class
- which is generally better because it allows the default value to be a subclass of the required type.
Upvotes: 8