Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics compile in Eclipse, but not in javac

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:

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);
    }

}

Compilation in javac returns:

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

This error now prevents building the project in Maven. As the Eclipse compiler is built to be more tolerant, I now have to assume the definition and usage of snippets as above static method is no valid Java?

like image 338
mtsz Avatar asked Nov 23 '12 17:11

mtsz


People also ask

Does Eclipse use javac?

javac compiler. However, both Eclipse Java compiler and javac implement the Java Language Specification (JLS), the bytecode they produce is almost the same. Except for some corner cases they may produce different bytecode or code compiles with Eclipse but not compiles with javac.

Why is my Java code not compiling?

It means that javac.exe executable file, which exists in bin directory of JDK installation folder is not added to PATH environment variable. You need to add JAVA_HOME/bin folder in your machine's PATH to solve this error. You cannot compile and run Java program until your add Java into your system's PATH variable.

How does the compiler translate Java generics?

Generics in Java are implemented using a type erasure mechanism. The compiler translates all type parameters in the source code to their bounding type in the class file. A type parameter's bounding type is Object if a bound type is not specified.

Does generics provide compile time safety?

Generics also provide compile-time type safety that allows programmers to catch invalid types at compile time.


1 Answers

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

like image 185
Raffaele Avatar answered Sep 22 '22 00:09

Raffaele