I have the following class with the following method.
public class MyClass {
public static <T> T getSomeThing(final int id, final java.lang.reflect.Type type, final Map<Integer, String> someThings) {
final String aThing = someThings.get(id);
if (aThing == null || aThing.isEmpty()) {
return null;
}
return GsonHelper.GSON.fromJson(aThing, type);
}
}
The GsonHelper provides me with some com.google.gson.GsonBuilder
public class GsonHelper {
public static final com.google.gson.Gson GSON = getGsonBuilder().create();
public static GsonBuilder getGsonBuilder() {
return new GsonBuilder().setPrettyPrinting()
.enableComplexMapKeySerialization()
.registerTypeAdapter(new com.google.gson.reflect.TypeToken.TypeToken<byte[]>() {
// no body
}.getType(), new Base64TypeAdapter())
.registerTypeHierarchyAdapter(Date.class, new DateTypeAdapter())
.registerTypeHierarchyAdapter(Pattern.class, new PatternTypeAdapter())
.registerTypeAdapterFactory(new ListTypeAdapterFactory())
.registerTypeAdapterFactory(new MapTypeAdapterFactory())
.registerTypeAdapterFactory(new SetTypeAdapterFactory());
}
}
Until Java 7 I was using this method like:
Map<Integer, String> allThings = new HashMap<>();
//FILL allThings with values
if(MyClass.getSomeThing(7, java.lang.Boolean.class, allThings)){
//do something
}
This worked fine. cause the method will return a Boolean and I can use this inside "if". But when I change to Java 8 this is not possible anymore. The compiler complains about:
Type mismatch: cannot convert from Object to boolean
//while this is working but would throw a JsonSyntaxException
final String myString = "myInvalidJsonString";
if(GsonHelper.GSON.fromJson(myString, java.lang.Boolean.class)){
//do something
}
I know that java.lang.Boolean can be null. And I could solve this issue with:
final Boolean b = MyClass.getSomeThing(7, java.lang.Boolean.class, allThings);
if(b){
//do something
}
But I am curious about why this is working with Java 7 and NOT in Java 8. (not answered)
What did they change? (not answered)
What is the reason for this compiler error when changing to Java 8? (answered)
Your method public static <T> T getSomeThing(final int id, final java.lang.reflect.Type t, final Map<Integer, String> someThings)
does not guarantee to return a Boolean
. It returns T
which is defined by the caller and could be anything, which means Object
.
The if statement can't know which type T
will have and hence can't guarantee to convert it to a boolean.
Why not change the signature to boolean?
public static boolean getSomeThing(final int id,
final java.lang.reflect.Type t,
final Map<Integer, String> someThings)
Or are you in search of this?
public static <T> T getSomeThing(final int id,
final Class<T> clazz,
final Map<Integer, String> someThings)
Than this code will compile and work:
public static void main(String[] args) {
if (getSomeThing(7, Boolean.class, emptyMap())) {
System.out.println("It works!");
}
}
public static <T> T getSomeThing(final int id,
final Class<T> clazz,
final Map<Integer, String> someThings) {
...
}