2011-04-23 66 views
10

比方說,我有以下設置的Java鑄造爲了

class A { 
    B foo(); 
} 

class C extends B { 

} 

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

我們知道a.foo()返回類型爲B.

當我做(C)a.foo(),是

  1. 鑄造a鍵入C然後試圖撥打foo()就可以了?
  2. 調用foo() on a並將結果轉換爲C

我發現很難確定,並一直只是打謹慎的額外括號一側(這是不是一個壞主意,爲便於閱讀,但現在我很好奇)

這是在具體參考ObjectInputStream.readObject(),雖然我不明白這將如何改變行爲。

+0

快速查找方法是在C.foo和B.foo中設置斷點並調試。那麼無論哪一個被擊中都會回答你的問題。順便問一下 – Spidy 2011-04-23 04:57:07

+0

嗯,我不知道Eclipse是否會讓我在Java核心類中設置斷點... :-) – corsiKa 2011-04-23 04:58:34

+0

你可以在你自己的引用庫上做這件事,所以我會認爲核心庫的反應是一樣的。只要你有源代碼連接,它可以讓你設置斷點(沒有測試過,看它們是否實際觸發) – Spidy 2011-04-23 05:02:35

回答

13

(C)a.foo()相當於(C)(a.foo()),即問題中的#2。

要獲得#1,您必須編寫((C)a).foo()

Java語言規範沒有在一個很好的,易於閱讀的總結中指定運算符優先級。

Appendix A of Sedgewick and Wayne的Java編程介紹有一個運算符優先級的綜合表。

The Java Programming Language的附錄B有一個運算符優先級表,但它不像Sedgewick's那樣完整。

grammar在Java語言規範仔細檢查可以確定鑄造和方法調用表達式的相對優先級中的問題:

 
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 {. Identifier }[IdentifierSuffix]匹配生產Expression3 : Primary {Selector} {PostfixOp}。綜合起來,我們可以看到方法調用表達式將被視爲一個單元(一個Expression3)被演員處理。

嗯,優先圖是容易按照...;)

+0

這似乎與我從Eclipse獲得的消息一致。你是否知道JLS中可以支持這個的任何東西?我無法找到它(我發現令人驚訝,我一定是簡單地用我的Google-fu使用了錯誤的關鍵字。) – corsiKa 2011-04-23 05:00:10

+0

@glowcoder:考慮研究[語法](http://java.sun.com /docs/books/jls/third_edition/html/syntax.html),特別是'Expression3'的定義。 – 2011-04-23 05:02:27

+0

不幸的是,我不知道Java官方出版物中關於運算符優先級的任何精闢概括。正如@克里斯說的,你必須從語法中解開它。其他人進行了這樣的分析,例如[Sedgewick and Wayne](http://introcs.cs.princeton.edu/11precedence/)。 – WReach 2011-04-23 05:17:13