TypeToken instantiation with generic list throwing RuntimeException: Missing type parameter

2,583 views
Skip to first unread message

Peter

unread,
Dec 19, 2011, 1:36:20 PM12/19/11
to google-gson
Using Gson 2.0, this code throws "java.lang.RuntimeException: Missing
type parameter." on line [Type t = new TypeToken<List<String>>()
{}.getType();]:

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;

import java.util.ArrayList;
import java.util.List;


public class Class1 {

public static void main(String[] args) {
List<String> l = new ArrayList<String>();
l.add("foo");
l.add("bar");

Type t = new TypeToken<List<String>>(){}.getType();

System.out.println(new Gson().toJson(l, t));
}
}

However, Gson 2.0 doesn't seem to need the Type in order to serialize
the list. This code works just fine:

import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.List;


public class Class1 {

public static void main(String[] args) {
List<String> l = new ArrayList<String>();
l.add("foo");
l.add("bar");

System.out.println(new Gson().toJson(l));
}
}

I based my use of TypeToken on the API docs (http://google-
gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/
Gson.html) and the User Guide (https://sites.google.com/site/gson/gson-
user-guide#TOC-Serializing-and-Deserializing-Gener).

What am I doing wrong?

Thanks,

-Peter

Jesse Wilson

unread,
Dec 20, 2011, 3:09:37 PM12/20/11
to google-gson
I can't reproduce this. When I run your first example, it prints this:
["foo","bar"]

Are you using ProGuard or another tool that could be interfering with
type information?

Peter

unread,
Dec 20, 2011, 6:29:56 PM12/20/11
to googl...@googlegroups.com
Thanks Jesse; your question guided me to the answer.

Not using proguard, but it turns out something similar is happening:

I've been using an IDE, and it's been using its own compiler, instead of using javac from the latest 1.6 JDK I've installed.  Changing the compiler from the IDE's compiler to the JDK compiler fixed my problem.

I don't like using the IDE's compiler and usually use javac; guess I missed that setting on this project.  Didn't think it would cause this type of error, but it must be doing some kind of optimization/obfuscation - like proguard does - that removes the type data.

Thanks,

-Peter

Inderjeet Singh

unread,
Dec 21, 2011, 3:16:47 AM12/21/11
to googl...@googlegroups.com
Peter, also to answer another question in your post: Yes, the newer version of Gson don't need type information for a list or collection. You can just call:

List<String> l = new ArrayList<String>();
l.add("foo");
l.add("bar");
System.out.println(new Gson().toJson(l));

HTH
Inder

Peter

unread,
Dec 21, 2011, 11:36:06 AM12/21/11
to googl...@googlegroups.com
Yeah, I was playing around more with that and found that if I use double-brace initialization to instantiate and populate a data structure:

List<String> l = new ArrayList<String>(){{add("foo");add("bar");}};

Gson requires type information in order to serialize it.  That's expected if you think about it (the outer set of braces creates an anonymous class, which anonymous class - not a List class - is what's being serialized by Gson), but it was surprising when I first tried it. :-)  This behavior holds for non-generic data structures as well.

Also, the Type supplied to Gson for the serialization doesn't need to be the exact type of the object being serialized - it just needs to be a class in the inheritance tree.  And, when using Generics, the Type doesn't even need to be created using the same Generic type as the object being serialized, at least for the simple cases I was using.

For example, this snippet of code compiles (within the structure of a class file, of course) and runs just fine:

List<String> l = new ArrayList<String>(){{add("foo");add("bar");}};
Type t = new TypeToken<Collection>(){}.getType();
System.out.println(new Gson().toJson(l, t));

As does this:

List<String> l = new ArrayList<String>(){{add("foo");add("bar");}};
Type t = new TypeToken<List<Integer>>(){}.getType();
System.out.println(new Gson().toJson(l, t));

This, however, throws a ClassCastException (as one would expect):

List<String> l = new ArrayList<String>(){{add("foo");add("bar");}};
Type t = new TypeToken<Map>(){}.getType();
System.out.println(new Gson().toJson(l, t));

Can't cast List to Map (d'oh).

Anyway, I'm having fun learning about the capabilities of Gson, and I think I now understand better how it goes about its business. :-)

Thanks,

-Peter

Karthick Raja

unread,
Jun 27, 2013, 4:44:40 AM6/27/13
to googl...@googlegroups.com
I am using the Proguard, throws "anonymous class(List<ClassName>) not found" exception. Is there any to change the procedure to obfuscate my java code.?
Reply all
Reply to author
Forward
0 new messages