2016-11-10 37 views
2

代碼:通過三元運算符傳遞方法的參數在Java中

public class Foo { 

    static void test(String s){ 
     System.out.println("String called"); 
    } 

    static void test(int s){ 
     System.out.println("int called"); 
    } 

    public static void main(String[] args) throws Exception { 

     test(5>8? 5:8);   // Line 1 
     test(5>8? "he":"ha"); // Line 2 

     test(5>8? 5:"ha");  // Line 3 

     System.out.println(5<8? 5:"ha"); //Line 4 
    } 
} 

當我在Line 3

Foo.java:24: error: no suitable method found for test(INT#1) 
       test(5>8? 5:"ha");    // Line 3 
       ^

三元操作執行此代碼我收到以下錯誤使用類似類型的不給錯誤。但是,使用不同類型的提示錯誤只方法調用​​但它適用於呼叫System.out.println(5<8? 5:"ha");

當我添加另一個重載方法static void test(Object s){},則//Line 3編譯。

任何人都可以請解釋我這種情況?

回答

4

Java中的每個表達式都有一個類型。在Java語言規範中有一些複雜的規則,在the conditional operator的部分告訴我們如何找到條件表達式的類型,如5 > 8 ? 5 : "ha"。但簡而言之,您總是可以獲得第二個和第三個參數都是最具體的類型。

  • 對於5 > 8 ? 5 : 8,既58int,所以這整個表達式的類型爲int
  • 對於5 > 8 ? "he" : "ha""he""ha"均爲String,所以此整個表達式的類型爲String
  • 對於5 > 8 ? 5 : "ha",適合5"ha"的最具體的類型是Object。所以這整個表達式的類型爲Object

現在,因爲你有test版本接受int並接受String,表達test (5 > 8 ? 5 : 8)test (5 > 8 ? "he" : "ha")兩個編譯。

但是,如果您沒有接受Object的版本test,則test (5 > 8 ? 5 : "ha")無法編譯。

這是過度簡化。這些規則比我所描述的要複雜得多,但這主要是因爲他們考慮了各種涉及操作數,自動裝箱和自動拆箱的案例。

+0

很好回答! –

+0

現在我明白如何確定三元運算符的返回類型。根據你的解釋,我想知道方法'System.out.println()'是否有一個重載的方法,它將Object作爲參數,並在PrintStream中找到了一個'public void println(Object x)'方法。如果你可以在你的答案中加入這一點,那麼這對其他人很有用。 –

+0

我覺得這是一個不同的問題。另外,大多數Java程序員都知道他們可以將任何他們喜歡的對象傳遞到'System.out.println'中。 –

0

您在評估表達式之前調用該方法。由於該方法沒有測試(對象o)的超載,所以它不起作用。

解析左側表達式後調用方法。

5>8?test(5):test("ha") 
0

當調用的函數的方法(在本例中)

test(5>8? 5:8);
意欲因此發送參數的括號內整個事情被認爲是參數並且存在處理此類無適當/合適的方法這種調用(其參數應該是Object),因爲您正在評估其中一個語句中的int和String。因此三元運算符不能在那裏實現。

因此可以使用這樣的代碼

(5 > 8) ? test(param1): test(param2); 


或創建它接受對象作爲參數,然後評估該測試方法裏面的東西另一測試方法。像這樣

void test(Object o){ 
    //manipulate things here 
}