15

我不得不发现我的项目中有 Java 代码,它在 Eclipse 中编译和运行良好,但在 javac 中引发编译错误。

一个独立的片段:

import java.util.HashSet;
import java.util.Set;

public class Main {

    public static void main(String[] args) {
    Set<Integer> setOfInts = new HashSet<Integer>();
    Set<Object> setOfObjects = covariantSet(setOfInts);
    }

    public static <S, T extends S> Set<S> covariantSet(Set<T> set) {
    return new HashSet<S>(set);
    }

}

javac 中的编译返回:

Main.java:10: incompatible types
found   : java.util.Set<java.lang.Integer>
required: java.util.Set<java.lang.Object>
    Set<Object> setOfObjects = covariantSet(setOfInts);
                                           ^

此错误现在阻止在 Maven 中构建项目。由于 Eclipse 编译器被构建为更宽容,我现在不得不假设上面的代码片段的定义和使用静态方法是无效的 Java?

4

5 回答 5

12

Sun 的 1.6 JDK 似乎无法推断出正确的类型。以下似乎适用于我的机器:

Set<Object> setOfObjects = Main.<Object, Integer>covariantSet(setOfInts);

请注意,您必须调用以类名为前缀的静态方法

于 2012-11-23T18:19:59.860 回答
10

你说的对。这个问题确实存在。Eclipse 不使用javac. 它使用自己的编译器。

实际上 javac 是“正确的”。泛型是擦除。类型S不包含在您的字节码中,因此 jvm 在运行时没有关于返回类型的足够信息。为了解决这个问题,改变方法原型如下:

public static <S, T extends S> Set<S> covariantSet(Set<T> set, Class<S> returnType)

现在返回类型在运行时传递给方法,编译器不应该抱怨。

于 2012-11-23T18:06:39.067 回答
0

在您的 Maven 构建脚本中,您已经设置了编译器版本。

在 Ant 中它看起来像这样:

<property name="source.version" value="1.5" />

搜索 1.3 或 1.4,或编译以在 maven 脚本中找到该值

值为 1.5 时,编译器将接受泛型(请参阅您的错误消息)

于 2012-11-23T18:03:21.543 回答
0

我知道这是个老问题,但我想提一下,函数可以写成:

import java.util.HashSet;
import java.util.Set;

public class Main {

public static void main(String[] args) {
        Set<Integer> setOfInts = new HashSet<Integer>();
        Set<Object> setOfObjects = covariantSet(setOfInts);
    }

    public static <S> Set<S> covariantSet(Set<? extends S> set) {
        return new HashSet<S>(set);
    }

}

它有点干净,您可以完全按照您的意图使用该功能(使用隐式通用类型)。

于 2013-10-18T14:35:28.173 回答
-1

将下一个插件添加到您的 pom.xml:

<plugin>
     <artifactId>maven-compiler-plugin</artifactId>
     <version>2.3.2</version>
     <configuration>
          <source>1.6</source>
          <target>1.6</target>
     </configuration>
</plugin>
于 2012-11-23T18:13:04.937 回答