2010-06-13 53 views
16

我有以下代碼:
這段java代碼的解釋是什麼?

public class Main { 
    public void method(Object o) 
    { 
      System.out.println("Object Version"); 
    } 
    public void method(String s) 
    { 
      System.out.println("String Version"); 
    } 
    public static void main(String args[]) 
    { 
      Main question = new Main(); 
      question.method(null);//1 
    } 
} 

爲什麼結果是「字符串版本」?以及爲什麼如果第一個方法需要StringBuffer對象時會出現編譯器錯誤?
另一種情況:如果第一種方法需要StringBuffer對象,而我寫入question.method("word");,則結果將爲「字符串版本」。爲什麼?爲什麼沒有編譯器錯誤?

+0

好奇。我期望編譯器在那裏發牢騷,但也許兩個參數類之間存在一種類型關係(「String」是更具體的)會改變事情,這是JLS中的情況嗎? 'StringBuffer'的情況很簡單,因爲它確實含糊不清。 – 2010-06-13 19:42:03

+1

@第三個問題:當然你不會得到一個錯誤。你傳遞一個字符串,所以帶有String參數的方法顯然會被調用。編譯器沒有什麼可以混淆的。 – someguy 2010-06-13 20:07:52

回答

23

JAVA規範說,在這種情況下,最具體的函數將被調用。由於String是Object的子類型 - 第二個方法將被調用。 如果將Object更改爲StringBuffer - 由於StringBuffer不是String的子類型,因此沒有具體的方法,反之亦然。在這種情況下,編譯器不知道調用哪個方法 - 因此是錯誤。

1

當看另一種情況時:

package com.snamellit;

public class Main { 
    public void method(Object o) { 
     System.out.println("Object Version"); 
    } 

    public void method(String s) { 
     System.out.println("String Version"); 
    } 

    public static void main(String args[]) { 
     Main question = new Main(); 
     question.method("word"); 
    } 
} 

如果第一方法tqkes一個StringBuffer和第二字符串,沒有混亂儘可能「字」是字符串,而不是一個StringBuffer。

在Java中,函數/方法的標識取決於3件事:名稱,類型參數(又名參數簽名)和類加載器。由於這兩種類型都有不同的參數簽名,因此編譯器可以輕鬆選擇正確的參數並且不會引發錯誤。

+0

但它_does_會產生一個錯誤:你能說一下嗎,彼得? – 2010-06-13 20:09:50

+0

感謝Peter.I認爲應該發生編譯器錯誤,因爲「word」是一個有效的StringBuffer值。 – 2010-06-13 20:15:32

+2

不,它是一個字符串,而不是一個StringBuffer。 StringBuffers是Strings的可變表親,它是不可變的,因此也是字符串的一個很好的模型。智者說:「如果有疑問,試試看」:System.out.println(「word」.getClass()。getName())將打印java.lang.String。 – 2010-06-13 20:55:28