Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type mismatch error in java 8

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)

like image 547
Naxos84 Avatar asked Mar 27 '17 05:03

Naxos84


People also ask

How do I fix type mismatch error?

The most important thing to do when solving the Type Mismatch error is to, first of all, locate the line with the error and then locate the part of the line that is causing the error. If your code has Error Handling then it may not be obvious which line has the error.

What is type mismatch in programming?

Sometimes, while writing code, programmers may ask that a value be stored in a variable that is not typed correctly, such as putting a number with fractions into a variable that is expecting only an integer. In such circumstances, the result is a type-mismatch error.

What is argument type mismatch?

You passed an argument of one type that could not be coerced to the type expected. For example, this error occurs if you try to pass an Integer variable when a Long is expected. If you want coercion to occur, even if it causes information to be lost, you can pass the argument in its own set of parentheses.


1 Answers

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) {
    ...
}
like image 75
Harmlezz Avatar answered Oct 08 '22 19:10

Harmlezz