【问题标题】:How to fix '<>' operator is not allowed for source level below 1.7 in 1.6?如何修复 1.6 中低于 1.7 的源级别不允许使用 '<>' 运算符?
【发布时间】:2014-05-15 12:00:47
【问题描述】:

我有一个 Java 1.6 Android 项目。我有一个无法编译的第三方代码:

import org.springframework.http.HttpEntity;
//...
HttpHeaders requestHeaders = new HttpHeaders();
//...
new HttpEntity<>(requestHeaders);

上面写着:1.7以下的源级别不允许使用''运算符

我不想将我的项目切换到 1.7。我已将该行更改为

new HttpEntity<Object>(requestHeaders);

现在可以正常编译了。

但是我的修复正确吗? Java 1.7 对空括号做了什么?

更新

该新对象被传递给接受HttpEntity&lt;?&gt; 参数的函数。我理解类型推断的想法,但我不明白 1.7 编译器从给定的代码行推断什么。

【问题讨论】:

标签: java android


【解决方案1】:

您缺少该行的第一部分,我确定创建 HttpEntity 不是为了将其丢弃(检查它保存到的引用的类型)。

Java

SomeGenericClass&lt;String&gt; foo = new SomeGenericClass&lt;String&gt;();

Java 1.7 允许它作为简写:

SomeGenericClass&lt;String&gt; foo = new SomeGenericClass&lt;&gt;();

【讨论】:

    【解决方案2】:

    您的修复几乎是正确的,而且无论如何也不危险。

    Object 是层次结构的根, 表示“让编译器推断类型”,因此在 1.7 中推断的任何类型都将是 Object 的特化。

    看到你的更新后:&lt;?&gt; 实际上是“通配符”(see here),所以Object 很好。

    【讨论】:

      【解决方案3】:

      菱形运算符只是被认为可以减少在赋值中重复键入泛型的不必要工作。

      代替

      ArrayList<MyClassWithThatStupidLongName> list = new ArrayList<MyClassWithThatStupidLongName>();
      

      你可以使用:

      ArrayList<MyClassWithThatStupidLongName> list = new ArrayList<>();
      

      然而,这是在 Java 7 中引入的,因为您似乎需要代码在较低版本上工作,您必须重新添加所有这些泛型,就像我在第一个清单中一样。

      【讨论】:

        【解决方案4】:

        您的修复是正确的。最好使用 `HttpEntitiy 的确切(通用)类型。

        &lt;&gt; 运算符背后的想法只是为了减少编译器可以从代码中隐式推断泛型类型的地方的冗长。

        正如post中所述

        Diamond Operator 减少了 Java 的一些冗长 泛型通过让编译器推断构造函数的参数类型 泛型类

        对这种运算符的需求来自于声明泛型类型的新实例的冗长。在 1.7 之前的 Java 版本中,您必须以这种方式定义泛型:

        List<MyClass> myClassCollection = new List<MyClass>();
        

        这显然是多余的,因为编译器可以很容易地理解对象构造中应该使用的类型。

        这个操作符带来的另一个很大的改进是泛型类型的返回:

        Java 1.7 之前:

        public List<MyClass> getMyClassCollection() {
           if(some condition) {
               return new ArrayList<MyClass>();
           } else {
               return LinkedList<MyClass>();
           }
        }
        

        java 1.7 之后:

        public List<MyClass> getMyClassCollection() {
           if(some condition) {
               return new ArrayList<>();
           } else {
               return LinkedList<>();
           }
        }
        

        这可能看起来微不足道,但实际上可能有一些流程可以让您省去一些这样的声明。当您想更改代码时,巨大的优势就来了。如果您现在将方法更改为返回List&lt;MyClassChild&gt;(其中MyClassChild 扩展MyClass),您只需要更改一个位置,而不需要更改几个位置。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-11-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-14
          相关资源
          最近更新 更多