以下定义在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 Object
是 TypeArgument
,但不是 ReferenceType
。)
例如,<Set<? extends Object>>
是 NonWildcardTypeArguments
但是<? extends Set<Object>>
不是。
所以是的,类型参数“中”有一个通配符,但它嵌套在树中的下一层。 NonWildcardTypeArguments
construct 只关心它内部的参数。
无论如何,正如 assylias 指出的那样,这种语法结构似乎不再存在,但我认为解释仍然很有趣。 (我尝试在 JLS 8 PDF 中搜索“NonWildcardTypeArguments”,但没有找到任何结果。)
关于Java 语法 : NonWildcardTypeArguments,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35162481/