2011-02-12 260 views
23

在Java中,創建靜態方法來訪問它,而無需任何對象實例。這對我來說很有意義。但最近我遇到了一件奇怪的事情,即Java中的靜態方法也可以通過它的對象實例來訪問。這對我來說很奇怪。你們中有人知道爲什麼這個功能是由Java提供的嗎?什麼是允許靜態方法訪問以及沒有實例的意義?可以使用對象實例訪問Java中的靜態方法

+1

關閉:爲什麼-心不是呼-A-靜態方法逐分路的-一個實例 - 一個誤差換的-java的CO](http://stackoverflow.com/questions/610458/why-isnt-calling-a-static-method-by-way-of -an-instance-an-error-for-the-java-co) – nawfal 2013-12-16 10:35:46

回答

16

這樣做的一個好處是,它允許您採用實例方法並將其轉換爲靜態方法,而無需修改任何現有代碼(除類之外),從而實現向後兼容性。我發現這很有用,很多次我遇到了可以變成靜態的實用方法 - 我可以添加static修飾符,並繼續我的方式。

+1

我沒有想到這個觀點。是的,如你所說,它提供了一個極端的兼容性選項。它的冒險精神和激動人心的理解Java指定的方式。再次感謝:) – 2011-02-12 12:33:59

+0

@Nate W。所以,向後兼容性是......如果你使用引用調用方法,被調用的方法可以是靜態的還是非靜態的?如果使用對象引用和使用類名稱來調用靜態方法是相同的,那麼如果方法有** synchronized **關鍵字,那麼它會鎖定一個'object'或'class.object'? – 2017-06-01 07:44:55

5

語義相同。編譯器足夠聰明,知道你的意思(即通過類訪問靜態方法)。 IDE會給你一個警告,告訴你這是不禮貌的:)

看看this question for more details。正如他們所說這可能會產生誤導,這就是爲什麼IDE會給你一個警告。

2

規格允許,但不是推薦。還有更多的IDE像Eclipse一樣在對象實例上標記一個靜態方法,並帶有警告。

0

雖然不好,但沒有任何強制性的理由來禁止它。

o.f(); 

,所以我們需要找到一個在o範圍命名爲f方法。有人可能會說靜態f當然也是在o範圍,即使f實際上是一個更大的範圍定義(o的類)

-2

另一個不錯(儘管有些黑客-Y)功能,它給你本質上是以對象的形式傳遞類引用的能力。所以說,例如,您有以下幾點:

public abstract class Animal { 
    public String name() { return "animal"; } 
} 

public class Dog extends Animal { 
    public String name() { return "dog"; } 
} 

如果然後運行以下命令:

Animal a = new Dog(); 
System.out.println(a.name()); 

...您將獲得:

dog 

這是什麼意思在實踐中,通過實例化對象調用靜態方法爲Java提供了一種一流功能。您可以使用抽象基類定義函數「type」,然後通過覆蓋子類中的靜態方法來實例化任何正確類型的函數。然後使用這些對象,就好像它們只是所討論的靜態方法的容器一樣。

爲了使這更具體一些,假設我們想要一個函數對字符串數組執行特定的字符串編碼,並且我們希望它將一個函數作爲一個函數對單個字符串執行編碼。我們希望參數根據所需的編碼而有所不同。沒有一流的功能,這是不可能的。但是,調用對象上的靜態方法爲我們提供了一個解決辦法:

public abstract class EncodingType { 
    public String encode(String s) { return s; } 
} 

public class Base64Encoding extends EncodingType { 
    public String encode(String s) { base64Encode(s); } // Assume "base64Encode" is defined 
} 

public class Rot13Encoding extends EncodingType { 
    public String encode(String s) { rot13Encode(s); } // Assume "rot13Encode" is defined 
} 

public class Encoder { 
    public String[] encodeArray(String[] s, EncodingType enc) { 
     for (int i = 0; i < s.length; i++) { 
      s[i] = enc.encode(s[i]); 
     } 
     return s; 
    } 
} 

你會這樣稱呼它:

Encoder e = new Encoder(); 
String[] strs = { ... }; 
strs = e.encodeArray(strs, new Rot13Encoding()); 
相關問題