假设我有以下设置
class A {
B foo();
}
class C extends B {
}
// later
A a = new A();
C theFoo = (C)a.foo();
我们知道
a.foo()
返回类型B。当我做
(C)a.foo()
时a
以键入C
,然后尝试在其上调用foo()
吗? foo()
上调用a
并将结果转换为C
类型? 我发现很难确定,并且总是在谨慎的情况下加上额外的括号(对于可读性来说,这不是一个坏主意,但现在我很好奇)
这是对
ObjectInputStream.readObject()
的特定引用,尽管我看不到它将如何改变行为。 最佳答案
(C)a.foo()
与(C)(a.foo())
等效,即问题中的#2。
要获得#1,您必须编写((C)a).foo()
。
Java语言规范没有在易于理解的摘要中指定运算符优先级。
Sedgewick和Wayne撰写的Java编程简介中的Appendix A具有完整的运算符优先级表。
The Java Programming Language的附录B有一个运算符优先级的表,但不如Sedgewick的完整。
仔细检查Java语言规范中的grammar可以确定所讨论的强制转换和方法调用表达式的相对优先级:
表达式:
Expression1 [AssignmentOperator Expression1]
表达式1:
Expression2 [Expression1Rest]
Expression1Rest:
?表达式:Expression1
表达式2:
Expression3 [Expression2Rest]
Expression2Rest:
{InfixOp Expression3}
Expression3 instanceof类型
表达式3:
PrefixOp表达式3
(表达式|类型)Expression3
主要 {选择器} {PostfixOp}
主:
ParExpression
NonWildcardTypeArguments(ExplicitGenericInvocationSuffix |此参数)
这个[参数]
super 后缀
文字
新造物主
标识符{。标识符} [IdentifierSuffix]
BasicType {[]} .class
无效类
相关作品以粗体显示。我们可以看到强制转换表达式与生产Expression3 : (Expression|Type) Expression3
相匹配。方法调用通过生产Expression3 : Primary {Selector} {PostfixOp}
与生产Primary: Identifier {. Identifier }[IdentifierSuffix]
匹配。放在一起,我们看到方法调用表达式将被视作要由强制转换作用的一个单元(一个Expression3
)。
嗯,优先级图表更容易遵循...;)