CoolJetdi
CoolJetdi

Reputation: 45

Generic abstract method & Functional interface & lambda expression

Question: If I use a lambda expression with functional interface, the abstract method in functional interface cannot have "independent" generic parameter type on its own? See example 3 for compile error.

Example 1: The concept that I have is that when I have an abstract method that declares a generic parameter type, the type is independent of the interface generics. T in test() method is independent of the T in interface MyInterface. See code below.

//Example 1
interface MyInterface<T> {
 
    <T> T test(T t);    
}

Example 2: If I apply lambda expression to the functional interface, it behaves interesting. See below.

Compile and run successfully. This is my understanding. Variable m is a raw type. Therefore, Java doesn't check the generic requirement for the test() method. Java doesn't care whether the generic type for test() abstract method is independent or dependent to the MyInterface. So this case the Object type is returned. See code below.

// Example 2
public class Test{
     
    public  static void main(String... args){
        MyInterface m = (x) -> x;        
    }
 
}
 
interface MyInterface<T> {
 
    <T> T test(T t);    
}

Example 3: Now, I declare the variable m as the parameterized type of type MyInterface. Compiler generates error. See code below.

// Example 3
public class Test{
     
    public  static void main(String... args){
        MyInterface<Integer> m = (x) -> x;     
    }
 
}
 
interface MyInterface<T> {
 
    <T> T test(T t);    
}
  
Test.java:12: error: incompatible types: invalid functional descriptor for lambda expression
                MyInterface<Integer> m = (x) -> x;
                                         ^
    method <T>(T)T in interface MyInterface is generic
  where T is a type-variable:
    T extends Object declared in method <T>test(T)
1 error

Example 4: Finally, I take out the generic parameter type from test() abstract method. It works fine. Program compiles. The abstract method "T test(T t)" is now dependent on the generic T of the interface MyInterface. See code below.

// Example 4
public class Test{
     
    public  static void main(String... args){
        MyInterface<Integer> m = (x) -> x;     
    }
 
}
 
interface MyInterface<T> {
 
    T test(T t);  
}

Upvotes: 0

Views: 485

Answers (1)

Andy Turner
Andy Turner

Reputation: 140318

If I use a lambda expression with functional interface, the abstract method in functional interface cannot have "independent" generic parameter type on its own?

Correct. Your example 3 demonstrates this. (Easier terminology here would be "the abstract method cannot be generic": generic methods are methods definining their own type parameters).

You can't do it with a lambda, you can do it with a method reference.

interface MyInterface<T> {
    <T> T test(T t);    
}

static <T> T foo(T t) { return t; }

public static void main (String[] args) throws java.lang.Exception
{
    MyInterface<?> x = Ideone::foo;  // Compiles OK
    MyInterface<?> y = a -> a;       // Error.
}

Ideone demo

You found the thing about lambdas already. Don't know if method references are useful to you.

Upvotes: 2

Related Questions