Java 语法 : NonWildcardTypeArguments

标签 java syntax jls

以下定义在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 construct 只关心它内部的参数。

无论如何,正如 assylias 指出的那样,这种语法结构似乎不再存在,但我认为解释仍然很有趣。 (我尝试在 JLS 8 PDF 中搜索“NonWildcardTypeArguments”,但没有找到任何结果。)

关于Java 语法 : NonWildcardTypeArguments,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35162481/

相关文章:

java - 异常创建对象

regex - Lex : Breaking up long regular expressions over multiple lines

python - 为什么我们在 Python 字典生成器中会有这种行为?

java - 在java中寻找简单的方法来仅大写字符串的第一个字母

Java Hibernate 多对一问题

java - 放松异常捕获的必要性

python - 为什么我在 'excpet'上收到语法错误?

java - Java8 中的模棱两可的重载——ECJ 还是 javac 正确?

Java final 字段编译时常量表达式

java - Java JLS 是否指定提升原始包装器类型?