爲什麼當我建立這個項目拋出一個錯誤(但不能同時運行單元測試)...不兼容的類型:推理變量E#1具有不兼容的上限枚舉<E#2>
protected <E extends Enum<E>> E getEnum(JSONObject jsonObject, String propertyName, Type type)
{
String jsonString = jsonObject.optString(propertyName, null);
return new GsonBuilder().create().fromJson(jsonString, type);
}
...而這完美的作品(注意區別 - 最後一個參數 - 這是未使用!):
protected <E extends Enum<E>> E getEnum(JSONObject jsonObject, String propertyName, Type type, Class<E> clazz)
{
String jsonString = jsonObject.optString(propertyName, null);
return new GsonBuilder().create().fromJson(jsonString, type);
}
錯誤:
warning: [options] bootstrap class path not set in conjunction with -source 1.7 C:\Projects\bla\bla\bla.java:32: error: incompatible types: inference variable E#1 has incompatible upper bounds Enum<E#2>,Termination
Termination termination = getEnum(jsonObject, "termination", Termination.TYPE);
where E#1,E#2 are type-variables:
E#1 extends Enum<E#1> declared in method <E#1>getEnum(JSONObject,String,Type)
E#2 extends Termination
我該怎麼做才能改善這一點?
編輯:
作爲附加信息:這是我的調用方法(使用第二實施例,第一示例中的錯誤信息已經被示出):
Termination termination = getEnum(jsonObject, "termination", Termination.TYPE, Termination.class).
這是該枚舉的簡化版本:
public enum Termination
{
@SerializedName("endDate")END_DATE,
@SerializedName("recurrenceCount")COUNT,
@SerializedName("forever")FOREVER;
public static final java.lang.reflect.Type TYPE = new TypeToken<Termination>(){}.getType();
}
現在我明白了 - 由於類型推斷 - 我顯然需要定義類的類型如第二個例子所示。但是,那不是我的問題。我想知道1:爲什麼Gson庫能夠像我一樣完成相同的操作(就我可以從下面的代碼示例中看到的),以及2:爲什麼在大多數情況下這不會編譯,而運行unittests沒問題。
GSON實例碼(稱爲在兩個實施例的方法):
@SuppressWarnings("unchecked")
public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
if (json == null) {
return null;
}
StringReader reader = new StringReader(json);
T target = (T) fromJson(reader, typeOfT);
return target;
}
編輯2:
顯然,當我離開了 '擴展Enum' 部分編譯器不再抱怨,所以我不需要將類型作爲參數傳遞。 (這看起來更像Gson的例子,這就是爲什麼它爲該代碼編譯的原因,但在第一個例子中沒有爲我編譯)。所以我的第一個例子,現在變成了:
protected <E> E getEnum(JSONObject jsonObject, String propertyName, Type type)
{
String jsonString = jsonObject.optString(propertyName, null);
return new GsonBuilder().create().fromJson(jsonString, type);
}
當然,我還是想擴展E至一定的方法只能用於返回枚舉。
剩下的問題:
- 我怎麼能提高代碼來解決這個問題?
- 爲什麼在不傳遞具體類型作爲參數的情況下工作,爲什麼在擴展Enum時不工作?
- 爲什麼運行unittests時編譯器不會抱怨原來的第一個例子?
聽起來很合理,但我見過的例子之前我不需要傳遞類類型作爲參數,只將泛型類型定義爲返回類型,而且顯然足夠了。 ... 如果沒有,那麼GsonBuilder是如何知道的? fromJson方法與我的第一個示例非常相似。 ... 我想它是從Type參數中讀取具體類型。那我該怎麼做?儘管如此,這並不能解釋爲什麼'fromJson'不需要類參數來提供必要的信息,就像您對我的示例所暗示的那樣。 –
研究類型推斷。必須有一些事情可以告訴編譯器推斷什麼。您沒有向我們展示完整的示例,因此我們不知道該方法是如何使用的。也許有一個提供信息的分配上下文,但沒有顯示你爲第一個例子做的事情。 –
我編輯了我的問題兩次,發現(部分)我正在尋找的答案。如果你能研究它並且再次回答(新)問題,我將不勝感激。 –