Java铸造订单 [英] Java casting order
问题描述
假设我有以下设置
class A {
B foo
}
C类扩展B {
}
//以后
A a = new A();
C theFoo =(C)a.foo();
我们知道 a.foo()
类型B。
当我(C)a.foo()
时,是
- 投入
a 键入
C
要调用foo()
吗? - 调用
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
- Casting
a
to typeC
then attempting to callfoo()
on it? - Calling
foo()
ona
and casting the result to typeC
?
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屋!