NonWildcardTypeArguments

NonWildcardTypeArguments

在jls https://docs.oracle.com/javase/specs/jls/se7/html/jls-18.html的第18章中定义了以下内容

NonWildcardTypeArguments:
    < TypeList >

TypeList:
    ReferenceType { , ReferenceType }

ReferenceType:
    Identifier [TypeArguments] { . Identifier [TypeArguments] }

TypeArguments:
    < TypeArgument { , TypeArgument } >

TypeArgument:
    ReferenceType
    ? [ (extends | super) ReferenceType ]

根据NonWildcardTypeArguments的名称,它不应允许通配符。但是下面的代码编译
public class NonWildcardTypeArgumentsTest {
    public void test(Test<java.util.Set<? extends Object>> args) {

    }
}

class Test<T> {}

此示例中的类型参数满足NonWildcardTypeArguments的定义,并且包含通配符:
<java.util.Set<? extends Object>>

我对此感到困惑。为什么有效?谢谢

最佳答案

通配符是Set的类型参数,而不是Test。这里的语法是一个树状结构,其中每个类型实参都适用于其外部的类型。

Test<T>
     ↓
    Set<E>
        ↓
    ? extends Object
NonWildcardTypeArguments仅要求每个类型参数是ReferenceType即可满足,因为Set<? extends Object>的形式为Identifier<TypeArgument>。 (? extends ObjectTypeArgument,但不是ReferenceType。)

例如,<Set<? extends Object>>NonWildcardTypeArguments,但<? extends Set<Object>>不是。

因此,是的,类型参数中有一个通配符,但它嵌套在树的某个级别下。 NonWildcardTypeArguments构造仅在乎其内部的参数。

无论如何,正如assylias所指出的那样,这种语法结构似乎已经不存在了,但我认为这种解释仍然很有趣。 (我尝试在JLS 8 PDF中搜索“NonWildcardTypeArguments”,但未提出任何建议。)

08-04 22:18