通用抽象方法 & 功能接口和 lambda 表达式

Generic abstract method & Functional interface & lambda expression

问题:如果我在函数式接口中使用lambda表达式,函数式接口中的抽象方法本身不能有“独立”的泛型参数类型?编译错误见示例3。

示例 1: 我的概念是,当我有一个声明泛型参数类型的抽象方法时,该类型独立于接口泛型。 test() 方法中的 T 独立于接口 MyInterface 中的 T。 请参阅下面的代码。

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

示例 2: 如果我将 lambda 表达式应用于功能接口,它的行为会很有趣。见下文。

编译并运行成功。 这是我的理解。变量 m 是原始类型。因此,Java 不检查 test() 方法的通用要求。 Java 不关心 test() 抽象方法的泛型类型是独立于还是依赖于 MyInterface。因此,在这种情况下,返回的是 Object 类型。 请参阅下面的代码。

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

示例 3: 现在,我将变量 m 声明为 MyInterface 类型的参数化类型。 编译器产生错误。 请参阅下面的代码。

// 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

示例 4: 最后,我从 test() 抽象方法中取出泛型参数类型。它工作正常。程序编译。 抽象方法“T test(T t)”现在依赖于接口 MyInterface 的泛型 T。 请参阅下面的代码。

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

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

正确。您的示例 3 证明了这一点。 (这里更简单的术语是“抽象方法不能是通用的”:通用方法是定义自己的类型参数的方法)。

你不能用 lambda 来做,你可以用方法引用来做。

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

您已经找到关于 lambda 的东西了。不知道方法引用对你有没有用。