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

关于静态变量类型中Java通配符使用的三个技术疑问

关于Oracle Java泛型示例代码的三个疑问解答

先贴出原示例代码:

static List<List<? extends Shape>>                     // 1
    history = new ArrayList<List<? extends Shape>>();  // 2

public void drawAll(List<? extends Shape> shapes) {    // 3
    history.addLast(shapes);                           // 4
    for (Shape s: shapes) {                            // 5
        s.draw(this);                                  // 6
    }
}

1. 第2行实例化对象的具体类型是什么?

第2行实例化的对象具体类型是ArrayList<List<? extends Shape>>。这里的通配符? extends Shape是作为嵌套泛型的实际类型参数存在的,它本身就是合法的实际类型参数——代表一类满足“元素是Shape子类(含自身)”的未知List类型。这个ArrayList可以容纳任何符合List<? extends Shape>的集合,比如ArrayList<Circle>、LinkedList<Rectangle>等。

2. 第4行调用addLast修改history为何可行?

教程提到的“通过带上限通配符类型的变量修改对象非法”,特指往带? extends通配符的集合内部添加非null元素(比如不能给List<? extends Shape>调用add(new Circle()),因为编译器无法确定集合实际存储的具体子类)。但第4行的场景完全不同:history的类型是List<List<? extends Shape>>,它的元素类型就是List<? extends Shape>,而参数shapes正好匹配这个类型,所以调用addLast(shapes)是类型完全兼容的操作——这是往外层List中添加符合要求的元素,而非往带通配符的内层List中添加元素,和教程禁止的场景无关。

3. 静态变量使用通配符为何不违反相关规则?

教程所说的“静态上下文不能引用类的类型参数”,指的是泛型类中,静态方法、初始化器或静态变量不能使用类声明时定义的类型参数(比如如果类是class Drawing<T>,静态变量不能用T)。但这里的? extends Shape是独立的通配符,并非类级别的类型参数,它直接限定了类型范围,没有依赖于类的泛型参数,因此静态变量使用这种通配符是完全合法的,和规则不存在矛盾。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:02:02