Home > Software design >  Java generic interface implementation cannot omit type parameter?
Java generic interface implementation cannot omit type parameter?

Time:07-09

I found that in Java I could use anonymous class to implement interface like Runnable (non-generic). I could also declare a variable without specifying type parameter on the right of "=". But I found for generic type, I cannot omit this:

import java.util.ArrayList;
import java.util.List;
interface Normal {
    Integer f();
    void g();
}
interface Generic<T> {
    T f();
    void g();
}
public class GenericInterface {
    public static void main(String[] args) {
        List<Integer> li = new ArrayList<>(); // ArrayList without type parameter, OK
        Runnable r = new Runnable() {
            @Override public void run() {}
        };
        Normal n = new Normal() { // declare implementation, OK.
            @Override public Integer f() {
                return new Integer(0);
            }
            @Override public void g() {}
        }; 
        Generic<Integer> i = new Generic<>() { // Why need type paramter here?
            @Override public Integer f() {
                return new Integer(0);
            }
            @Override public void g() {}
        };
    }
}

As you could see, javac report compilation failure for this line:

Generic<Integer> i = new Generic<>() {

While the compiler is smart enough to compile List<Integer> li = new ArrayList<>(), when compiler already know the real type from the left of this statement, why it still needs me to write new Generic<Integer>() { ?

Or Java prevents generic interface implementation without specifying the type parameter? What is the reason?

CodePudding user response:

In Java 8 the compiler gives this error:

GenericInterface.java:23: error: cannot infer type arguments for Generic<T>
        Generic<Integer> i = new Generic<>() { // Why need type paramter here?
                                        ^
  reason: cannot use '<>' with anonymous inner classes
  where T is a type-variable:
    T extends Object declared in interface Generic
1 error

I cannot see where this is explicitly forbidden in the Java 8 edition of the JLS (but I might have missed it).

In any case, this is permitted in Java 9 and later. It was one of the changes made as part of Project Coin (JEP 213):

"3. Allow diamond with anonymous classes if the argument type of the inferred type is denotable. Because the inferred type using diamond with an anonymous class constructor could be outside of the set of types supported by the signature attribute, using diamond with anonymous classes was disallowed in Java SE 7. As noted in the JSR 334 proposed final draft, it would be possible to ease this restriction if the inferred type was denotable."

This improvement was delivered in Java 9.


What is the reason?

The technical reason is given in the quoted text above.

CodePudding user response:

Because you have a method f() that needs the generic type to be overloaded.

  • Related