不兼容的类型:推断变量E#1的上限不兼容Enum <E#2> - java

为什么在我构建项目时(而不是在运行单元测试时)会抛出错误...

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:为什么在运行单元测试时大多数情况下无法编译没问题

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:

显然,当我省略“扩展枚举”部分时,编译器不再抱怨了,因此我不需要将类型作为参数传递。 (这看起来更像是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时,编译器为什么不抱怨原始的第一个示例?

参考方案

第一个示例中的type参数无法知道要替换的具体类型。参数列表中必须有解决该问题的信息。在第二个示例中,Class<E>参数提供了必要的信息。

休眠映射<键,设置<值>> - java

我有以下表格:@Entity @Table(name = "events") Event --id --name @Entity @Table(name = "state") State --id --name @Entity @Table(name = "action") Action --id …

无法从ArrayList <String>转换为List <Comparable> - java

当我写下面的代码时,编译器说 无法从ArrayList<String>转换为List<Comparable>private List<Comparable> get(){ return new ArrayList<String>(); } 但是当我用通配符编写返回类型时,代码会编译。private List&l…

合并List <T>和List <Optional <T >> - java

鉴于: List<Integer> integers = new ArrayList<>(Arrays.asList( 10, 12 )); List<Optional<Integer>> optionalIntegers = Arrays.asList( Optional.of(5), Optional.em…

实例化类型<?>的泛型类 - java

我正在为SCJP / OCPJP学习,并且遇到了一个对我来说很奇怪的示例问题。该示例代码实例化了两个通用集合:List<?> list = new ArrayList<?>(); List<? extends Object> list2 = new ArrayList<? extends Object>(); …

List <Dog>是List <Animal>的子类吗?为什么Java泛型不是隐式多态的? - java

我对Java泛型如何处理继承/多态感到困惑。假设以下层次结构-动物(父母)狗-猫(儿童)因此,假设我有一个方法doSomething(List<Animal> animals)。根据继承和多态性的所有规则,我假设List<Dog>是List<Animal>,而List<Cat>是List<Animal&g…