Java casting order

前端 未结 2 716
不知归路
不知归路 2020-12-10 12:54

Let\'s say I have the following setup

class A {
    B foo();
}

class C extends B {

}

// later
A a = new A();
C theFoo = (C)a.foo();

We k

相关标签:
2条回答
  • 2020-12-10 13:29

    Method call has a higher operator precedence than type casting, so (C) a.foo() will first call a.foo() and cast the result to type C. In contrast, ((C) a).foo() first casts a to type C and then calls its foo() method.

    0 讨论(0)
  • 2020-12-10 13:37

    (C)a.foo() is equivalent to (C)(a.foo()), i.e. #2 in the question.

    To get #1, you would have to write ((C)a).foo().

    The Java language specification does not specify operator precedence in a nice, easy-to-read summary.

    Appendix A of Introduction to Programming in Java by Sedgewick and Wayne has a comprehensive table of operator precedence.

    Appendix B of The Java Programming Language has a table of operator precedence, but it is not as complete as Sedgewick's.

    A close inspection of the grammar in the Java Language Specification can determine the relative precedences of the cast and method call expressions in question:

    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
    

    The relevant productions are bolded. We can see that a cast expression matches the production Expression3 : (Expression|Type) Expression3. The method call matches the production Expression3 : Primary {Selector} {PostfixOp} by means of the production Primary: Identifier {. Identifier }[IdentifierSuffix]. Putting this together, we see that the method call expression will be treated as a unit (an Expression3) to be acted upon by the cast.

    Hmmm, the precedence chart is easier to follow... ;)

    0 讨论(0)
提交回复
热议问题