I had to discover I have Java code in my project, which compiles and runs fine in Eclipse, but throws a compilation error in javac.
A self-contained snippet:
Add the next plugin to your pom.xml:
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
In your Maven build skript you have set the compiler version.
In Ant it lookes like this:
<property name="source.version" value="1.5" />
search for 1.3 or 1.4, or compile to find that value in the maven skripts
With value 1.5 the compiler will accept the generics (see your error messages)
It seems that Sun's 1.6 JDK can't infer the correct type. The following seems to work on my machine:
Set<Object> setOfObjects = Main.<Object, Integer>covariantSet(setOfInts);
Note that you must invoke the static method prefixed with the class name
I know it's old question, but I want to mention, the function could be written as:
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);
}
}
It's a little bit cleaner and you can use the function exactly how you intented to(with implicit generic typing).
You are right. This problem indeed exists. Eclipse does not use javac
. It uses its own compiler.
Actually javac is "right". Generics are erasures. Type S
is not included into your byte code, so jvm does not have enough information about the return type at runtime. To solve the problem change the method prototype as following:
public static <S, T extends S> Set<S> covariantSet(Set<T> set, Class<S> returnType)
Now the return type is passed to the method at runtime and compiler should not complain.