2017-05-08 61 views
1

我正在使用GSON來解析Java中的json。當我想從一個JSON字符串的整數列表,我的代碼看起來是這樣的:找出GSON的TypeToken是否包含列表?

Type type = new TypeToken<List<Integer>>(){}.getType(); 

    List<Integer> result = null; 
    try { 
     result = new Gson().fromJson(jsonStringGoesHere, type); 
    } catch (JsonSyntaxException e) { 
     e.printStackTrace(); 
    } 

如果jsonStringGoesHere是一個空字符串或NULL,result也爲空。

但是,如果Collection的值等於null,這被認爲是不好的做法,所以我寧願在這種情況下有一個空的List而不是null。

所以基本上這就是我想現在要做的:如果result是空的,我要檢查,如果typeList(或List亞型)。如果爲true,我會使結果成爲一個空ArrayList。我如何檢查type是否包含ListList的子類型?

我的嘗試是檢查if(type instanceof Collection) - 但返回false。

我的下一個嘗試是採取type.getTypeName()它返回字符串java.util.List<java.lang.Integer>,並試圖從創建一個對象:

 Class c = Class.forName(type.getTypeName()); 
     Object o = c.newInstance(); 
     if(o instanceof List){ 
      System.out.println("it's working!"); 
     } 

但這拋出​​。

任何想法如何使這項工作?

+0

將List更改爲ArrayList中的Type Type = new TypeToken >(){}。getType();'。檢查http://stackoverflow.com/questions/4818228/how-to-instantiate-a-java-util-arraylist-with-generic-class-using-reflection – Ibrahim

+0

@Ibrahim這樣做,'結果'仍爲空,'' instanceof'仍然返回false,並且創建newInstance()仍會拋出java.lang.ClassNotFoundException:java.util.ArrayList 。 – user2015253

回答

1

我試圖檢查if(type instanceof Collection) - 但返回false

這不會起作用,因爲TypeCollection不是「相互澆注料」,並在不同的層次存在。

我的下一個嘗試是採取type.getTypeName()它返回字符串java.util.List<java.lang.Integer>

這將不能工作。 Class.forName通過完全限定名稱(簡單來說,文件在CLASSPATH中表示的內容)返回現有的Class<?>實例,但從未 - 參數化類(類不是可參數化的類,但可以是具有參數化超類的子類 - 這就是在類型令牌的引擎下)。因此,Class.forName("java.util.List")是有道理的,但Class.forName("java.util.List<String>")沒有。

注意Type的東西,可以代表一個類型TypeToken<T>服務於這個目的。只要看看它是如何聲明的 - 你會更好地理解它。更多的是,其子接口ParameterizedType可以保存類型參數,這可以通過TypeToken生成,或者手動構建(像往常一樣 - 只需看看接口聲明)。 TypeToken通常使用匿名基類參數化來獲取類型參數,這就是爲什麼它們是這樣設計的:良好的編譯時支持+在Google Guava,Jackson,Spring Framework中有類似的技術(但它會很好如果Java可以支持類似java.util.List<Integer>.type來獲取參數化類型實例)。從後面的Gson版本開始,您甚至可以使用TypeToken.getParameterized(...)這只是一種簡便的方法來創建參數化類型。

您要找的是「class-instanceof」或「a-subclass-of」(如果可以這樣稱呼它):Class.isAssignableFrom(...)。此實例方法檢查一個類是否相同或另一個類的子類。說,

SuperClass.class.isAssignableFrom(SubClass.class) 

總是返回true。所以,你只需要檢查是這樣的:

final Type type = new TypeToken<List<Integer>>() { 
}.getType(); 
final TypeToken<?> typeToken = TypeToken.get(type); 
System.out.println(List.class.isAssignableFrom(typeToken.getRawType())); 

或者更短:

final TypeToken<List<Integer>> typeToken = new TypeToken<List<Integer>>() { 
}; 
System.out.println(List.class.isAssignableFrom(typeToken.getRawType())); 

兩個返回true。需要注意的是類型令牌通過getRawType()回到Class<?>實例,但不getType()因爲後者可能代表不是一類(比方說,會是什麼Collection<String>.class.isAssignableFrom(List<Integer.class>)回報呢?)

此外,您還可以提取類型標記及其類型static final領域,因爲它們是意味着不可改變的值,並且不應在運行時更改。

0

在Java中Java的泛型部分在編譯時發揮作用,因此它在運行時不可用,這就是您得到該異常的原因。所以如果你想創建類收集類型使用反射,那麼你必須刪除通用部分。

而且列表設置地圖是它們不能被直接實例化接口。因此,爲了創建一個對象,你必須使用其實施的一個,像ArrayList中LinkedList的

相關問題