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

Java通配符参数困惑:为何父类类型变量可调用子类方法?

问题解答

先贴出你的代码方便讨论:

public class A {
    void meth1() {}
}
public class B extends A {
    void meth2() {}
}

public class generic_class<T extends A> {
    T var1;

    public void meth4(generic_class<? extends B> gc) {
        gc.var1.meth2();
    }
}

你困惑的点在于:泛型擦除后var1的类型应该是上限A,为什么能调用B独有的meth2()?

核心要区分编译期检查和运行时擦除两个阶段:

  • 编译期:编译器靠通配符约束做类型校验
    你声明的generic_class<? extends B>告诉编译器:这个gc的类型参数必然是B或者B的子类。所以编译器会把gc.var1的编译期类型判定为B(通配符? extends B的上限),而非A。既然编译器确定var1肯定是B或其子类的实例,自然允许调用B中定义的meth2()。

  • 运行时:泛型擦除后靠动态绑定执行正确方法
    运行时泛型信息确实会被擦除,var1的静态类型会变成A,但此时调用方法是基于实际对象的运行时类型的动态绑定。因为var1实际指向的是B或其子类的对象,JVM会找到对应对象的meth2()方法执行,不会出现找不到方法的问题。

总结来说,编译期的通配符约束保证了代码的合法性,运行时的动态绑定保证了方法能正确执行,泛型擦除并没有打破这个逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 15:59:57