假设我有以下设置
class A { B foo(); } class C extends B { } // later A a = new A(); C theFoo = (C)a.foo();
我们知道a.foo()返回类型B.
当我做(C)a.foo(),是吗
>将一个转换为C类,然后尝试调用foo()呢?
>调用foo()并将结果转换为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的仔细检查可以确定有关的转换和方法调用表达式的相对优先级:
Expression: Expression1 [AssignmentOperator Expression1]] Expression1: Expression2 [Expression1Rest] Expression1Rest: ? Expression : Expression1 Expression2 : Expression3 [Expression2Rest] Expression2Rest: {InfixOp Expression3} Expression3 instanceof Type Expression3: PrefixOp Expression3 ( Expression | Type ) Expression3 Primary {Selector} {PostfixOp} Primary: ParExpression NonWildcardTypeArguments (ExplicitGenericInvocationSuffix | this Arguments) this [Arguments] super SuperSuffix Literal new Creator Identifier { . Identifier }[ IdentifierSuffix] BasicType {[]} .class void.class
相关制作粗体.我们可以看到一个转换表达式与生产Expression3:(Expression | Type)Expression3匹配.方法调用通过生产Primary:Identifier {匹配生产Expression3:Primary {Selector} {PostfixOp}.标识符} [IdentifierSuffix].将它们放在一起,我们看到方法调用表达式将被视为一个单元(一个Expression3),由演员进行操作.
嗯,优先图更容易遵循…)