Java铸造订单 [英] Java casting order

查看:110
本文介绍了Java铸造订单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下设置

  class A {
B foo
}

C类扩展B {

}

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

我们知道 a.foo()类型B。



当我(C)a.foo()时,是


  1. 投入 a 键入 C 要调用 foo()吗?

  2. 调用 a 并将结果强制类型转换为 C

我发现很难确定,并且总是只是在额外的括号(这不是一个坏主意,为了可读性,但现在我很好奇) / p>

这是具体引用 ObjectInputStream.readObject(),虽然我没有看到这将改变行为。

解决方案

(C)a.foo() (C)(a.foo()),即问题中的#2。



,你必须写((C)a).foo()



Java语言规范



Sedgewick和Wayne的编程简介附录A 提供了运算符优先级的全面表格。



附录B Java编程语言有一个运算符优先级表,但它不如Sedgewick的完整。



仔细检查语法在Java语言规范中可以确定所讨论的转换和方法调用表达式的相对优先级:

 
表达式
Expression1 [AssignmentOperator Expression1]]

Expression1:
Expression2 [Expression1Rest]

Expression1Rest:
?表达式:Expression1

Expression2:
Expression3 [Expression2Rest]

Expression2Rest:
{InfixOp Expression3}
Expression3 instanceof Type

Expression3:
PrefixOp Expression3
(Expression | Type)Expression3
} {PostfixOp}

主要:
ParExpression
NonWildcardTypeArguments(ExplicitGenericInvocationSuffix | this Arguments)
this [Arguments]
super SuperSuffix
Literal
new Creator
标识符{。 Identifier} [IdentifierSuffix]
BasicType {[]} .class
void.class

相关产品加粗。我们可以看到一个转换表达式匹配生产 Expression3:(Expression | Type)Expression3 。方法调用通过生产 Primary:Identifier {匹配生产 Expression3:Primary {Selector} {PostfixOp} Identifier} [IdentifierSuffix] 。把它们放在一起,我们看到方法调用表达式将被视为一个单元( Expression3 ),以便被强制转换。



嗯,优先顺序图更容易遵循...;)


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 know a.foo() returns type B.

When I do (C)a.foo(), is it

  1. Casting a to type C then attempting to call foo() on it?
  2. Calling foo() on a and casting the result to type C?

I'm finding it difficult to determine, and have always just played on the side of caution with extra parenthesis (which isn't a bad idea, for readability, but now I'm curious)

This is in specific reference to ObjectInputStream.readObject() although I don't see how that would change the behavior.

解决方案

(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... ;)

这篇关于Java铸造订单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆