简体   繁体   中英

GSON using Java generics

I am trying to get right a method called fromJSON using the GSON library

public <T> T fromJSON( String object, Class<T> classObject )
{
    return gson.fromJson( object, classObject );
}

The fact is that I have some classes that one member could be defined using Java generics. For example I can create a new ValidationResult<User>(), ValidationResult<Image>() or ListResult<User>(), ListResult<Image>() , etc... so the problem I'm facing is that I need to tell GSON which T it should use. Here is where I am running in an issue, cause my current code is converting the JSON object into a ValidationResult or ListResult , but the generic object is not treated as User , Image , etc. It is just converted to a LinkedTreeMap for example.

I tried some answers I have found in Stackoverflow, but I still am not able to get it right.

Using a generic type with Gson
Google Gson - deserialize list<class> object? (generic type)
Deserializing Generic Types with GSON

Can someone put myself in the right path? If possible share some code that I can use as guide.

Because of type erasure ValidationResult and ValidationResult<User> are the same type. There will only ever be one Class object for that type. Because Gson only knows about ValidationResult through that Class object, it has to use a default for the generic type. In this case, it uses a LinkedHashMap .

The easiest solution is to provide a TypeToken , which is kind of a hack to get around type erasure (but not really). You can use it like so

gson.fromJson(json, new TypeToken<ValidationResult<User>>() {}.getType());

Through the Type , Gson has access to the generic type argument. Note how I've hardcoded the type User as an argument. You have to use an actual type here for Gson to get the actual type. If you use a generic type parameter, Gson will get a generic type parameter as a value and again will not know how to use it. I explain why here .

Another solution is to create a subtype of ValidationResult like

public class UserValidationResult extends ValidationResult<User> {}

and pass the Class object of that to your method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM