You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 11泛型类构造器重载调用逻辑疑问咨询

Java泛型构造器重载疑问解析

定义的泛型类

class CardboardContainer<T> {
    T myField;

    CardboardContainer(T myField) {
        System.out.println("In T constructor");
        this.myField = myField;
    }

    <T extends Number> CardboardContainer(T myField) {
        System.out.println("In T2 constructor");
//        this.myField = myField;
    }
}

实例化操作

CardboardContainer<String> n1 = new CardboardContainer<String>("Hello"); // 调用T构造器
CardboardContainer<String> n2 = new CardboardContainer<String>(3); // 调用T2构造器
CardboardContainer<Integer> n22 = new CardboardContainer<Integer>(3); // 调用T构造器
CardboardContainer<String> n3 = new <Integer>CardboardContainer<String>(3); // 调用T2构造器

疑问解答

1. 为什么n1会调用第一个构造器而非第二个?

第一个构造器的参数类型是类的泛型T,这里实例化时T被指定为String,传入的"Hello"是String类型,完全匹配第一个构造器的参数要求。而第二个构造器的泛型T是构造器自身的泛型(和类的泛型T重名但属于不同作用域),它要求参数必须是Number的子类,String不满足这个约束,因此编译器只能选择第一个构造器。

2. 将类型从String改为Integer后,n22为何调用第一个构造器?n2与n22的构造器选择由什么决定?

  • 对于n22:实例化时类的泛型T是Integer,第一个构造器的参数类型就是Integer,传入的3自动装箱为Integer,完全匹配第一个构造器的参数;而第二个构造器虽然也接受Integer(因为Integer extends Number),但编译器会优先选择参数类型与类泛型完全匹配的构造器,而非带有额外泛型约束的构造器,所以最终调用第一个。
  • 对于n2:类的泛型T是String,第一个构造器需要String类型参数,但传入的3是Integer,无法匹配第一个构造器;此时编译器会寻找其他匹配的构造器,第二个构造器的泛型可以绑定为Integer,满足extends Number的约束,参数类型匹配,因此调用第二个构造器。

核心逻辑是:优先匹配参数类型与类泛型一致的构造器,若不匹配,再检查是否符合带额外泛型约束的构造器的参数要求。

3. 我原本认为n3会调用第一个构造器,为何实际调用了第二个?

new <Integer>CardboardContainer<String>(3)中的<Integer>是显式指定了构造器自身的泛型参数,这会强制编译器使用第二个带<T extends Number>泛型约束的构造器。即便你期望使用类泛型String对应的第一个构造器,但显式指定构造器泛型的操作,直接告诉编译器要调用带有该泛型约束的构造器,因此最终调用第二个。

内容的提问来源于stack exchange,提问作者summerisbetterthanwinter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 02:35:02