Java 理解构造函数的有界泛型参数

Java 理解构造函数的有界泛型参数,java,generics,Java,Generics,我很困惑,为什么第一个代码段正在编译,而第二个代码段没有 我假设在这两种情况下,泛型参数T描述了相同的可能类型集,因此它们是等价的 第一个示例 public class Main { static Function<B, Integer> f = (b) -> 1; Main() { this(f); } <T extends A> Main(Function<T, Integer> f) {

我很困惑,为什么第一个代码段正在编译,而第二个代码段没有

我假设在这两种情况下,泛型参数T描述了相同的可能类型集,因此它们是等价的

第一个示例

public class Main {

    static Function<B, Integer> f = (b) -> 1;

    Main() {
        this(f);
    }

    <T extends A> Main(Function<T, Integer> f) {

    }

}

class A {    }

class B extends A {    }
公共类主{
静态函数f=(b)->1;
Main(){
这(f);
}
主要(功能f){
}
}
A类{}
类B扩展了{}
第二个示例:

public class Main<T extends A> {

    static Function<B, Integer> f = (b) -> 1;

    Main() {
        this(f);
    }

    Main(Function<T, Integer> f) {

    }

}

class A {    }

class B extends A {    }
公共类主{
静态函数f=(b)->1;
Main(){
这(f);
}
主要(功能f){
}
}
A类{}
类B扩展了{}
产生以下错误:

构造函数主(函数)未定义


在第二个示例中,您在类级别引入了类型参数T,但是您将始终使用类B传递一个固定函数。如果用Main«A»实例化Main会怎么样?您的代码不是类型安全的。


在第一个示例中,这不是问题,因为函数上的类型参数仅在每次调用时确定

在第一个代码中,
T
参数的作用域为方法:

<T extends A> Main(Function<T, Integer> f) {

}
这些措施也将发挥作用:

static Function<B, Integer> fb = (b) -> 1;
static Function<C, Integer> fc = (b) -> 1;
static Function<D, Integer> fd = (b) -> 1;
问题是这里的
T
可以是
A
B
A
的任何其他子类,这取决于类的客户端使用的泛型类型。

因此,
函数
不能分配给
函数
,编译失败

这些例子不一样

示例1-只有构造函数#2是泛型的,但构造函数#1和类不是泛型的

因此编译器只需在constr#1中推断constr#2的参数类型。这很好,也是可能的

示例2-整个类是泛型的。 因此,constr#1的编译器已经使用类型
T扩展了
。现在它检查对constr#2的调用。它指出
T扩展A
并不等于
B
T
可以是扩展
A
的任何其他类)

为了澄清-对于泛型类,类型推断(泛型类型的解析)不能在构造函数中发生。它发生在从外部调用构造函数的地方。里面已经给出了定义


与该示例相比,我们只使用方法(构造函数)类型推断,这可以在constr#1中完美实现。

您的错误消息告诉您什么?
static Function<B, Integer> fb = (b) -> 1;
static Function<C, Integer> fc = (b) -> 1;
static Function<D, Integer> fd = (b) -> 1;
public class Main<T extends A> {

    Main(Function<T, Integer> f) {

    }

}