Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics function call not compiling in java 8 extending multiple interfaces

Running Java 1.8 JavaSE-1.8 (jdk1.8.0_20)

This class:

public class SimpleQuestion {

    public static void main(String[] args) {
        DoNothing();
        DoNothing2();
        DoNothing3();
        DoNothing4();
    }    

    public interface Interface1 {
        public void go();
    }

    public interface Interface2<X> {
        public X go2();
    }

    private static <X, T extends Interface2<X> & Interface1> void DoNothing() {
        return;
    }

    private static <X, T extends Interface2 & Interface1> void DoNothing2() {
        return;
    }

    private static <X, T extends Interface2<X>> void DoNothing3() {
        return;
    }

    private static <T extends Interface2<T> & Interface1> void DoNothing4() {
        return;
    }    

}

gives the compile error:

The method DoNothing() in the type SimpleQuestion is not applicable for the arguments ()

Why that one and not DoNothing2,3, and 4?

like image 546
user2051552 Avatar asked Oct 03 '14 21:10

user2051552


People also ask

What are some examples of generic interfaces in Java?

Comparable interface is a great example of Generics in interfaces and it’s written as: package java.lang; import java.util.*; public interface Comparable<T> { public int compareTo (T o); } In similar way, we can create generic interfaces in java. We can also have multiple type parameters as in Map interface.

Why can't you extend a generic interface twice with different parameters?

An answer by Chris Povirk describes one: [A reason for the restriction is] the possibility of specifying illegal types. Specifically, extending a generic interface twice with different parameters. I can't come up with a non-contrived example, but:

Can a functional interface extend another interface in Java?

A functional interface can extends another interface only when it does not have any abstract method. In the following example, a functional interface is extending to a non-functional interface. Java provides predefined functional interfaces to deal with functional programming by using lambda and method references.

What is generics in Java?

Generics means parameterized types. The idea is to allow type (Integer, String, … etc, and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types. An entity such as class, interface, or method that operates on a parameterized type is called ...


1 Answers

The error message appears to be referring to a failure of the algorithm defined in section 18.5.1 of the spec.

For DoNothing, the algorithm proceeds as follows (using the terminology from the above link):

  • The type parameters are

    P1 = X

    P2 = T extends Interface2<X> & Interface1

    and I'll use a1 and a2 for the corresponding inference variables.

  • The initial bound set is

    B0 = {a1 <: Object, a2 <: Interface2<a1>, a2 <: Interface1}

  • There are no arguments, so no extra bounds are added at this point (B2 = B0).

  • There is a dependency of a2 on a1, so we try to resolve a1 first. It has a proper upper bound of Object, so we instantiate it to this. Incorporating a1 = Object involves adding the bound

    a2 <: Interface2<Object>

  • Next we resolve a2. This now has two proper upper bounds, so we instantiate a2 to their glb:

    a2 = Interface2<Object> & Interface1

  • Every variable now has an instantiation, so resolution has succeeded.

Hence, contrary to the error message, the invocation of DoNothing ought to be applicable. This appears to be a bug in your Java compiler.

like image 147
Mark Brown Avatar answered Oct 21 '22 06:10

Mark Brown