2010-10-11 198 views
52

請參見下面的代碼片段:靜態方法和非靜態方法有什麼區別?

代碼1

public class A { 
    static int add(int i, int j) { 
     return(i + j); 
    } 
} 

public class B extends A { 
    public static void main(String args[]) { 
     short s = 9; 
     System.out.println(add(s, 6)); 
    } 
} 

代碼2

public class A { 
    int add(int i, int j) { 
     return(i + j); 
    } 
} 

public class B extends A { 
    public static void main(String args[]) { 
    A a = new A(); 
     short s = 9; 
     System.out.println(a.add(s, 6)); 
    } 
} 

是這些代碼段之間的區別?兩者都輸出15作爲答案。

回答

114

靜態方法屬於類本身和非靜態(又名實例)方法屬於被從該類生成的每個對象。如果你的方法做了一些不依賴於它的類的個別特徵的東西,把它變成靜態的(它會使程序的足跡更小)。否則,它應該是非靜態的。

例子:

class Foo { 
    int i; 

    public Foo(int i) { 
     this.i = i; 
    } 

    public static String method1() { 
     return "An example string that doesn't depend on i (an instance variable)"; 
    } 

    public int method2() { 
     return this.i + 1; // Depends on i 
    } 
} 

你可以調用靜態方法是這樣的:Foo.method1()。如果你用method2來嘗試,它會失敗。但是,這將工作:Foo bar = new Foo(1); bar.method2();

+0

訪問說明符(公用)是否影響靜態方法訪問? 類似於如果您的方法名稱將是靜態字符串method1()會發生什麼? – 2017-08-08 06:14:10

+0

也可以將該靜態方法放入UtililyClass中? – karlihnos 2017-11-15 15:00:23

7

靜態方法屬於類 和非靜態方法屬於一個類的一個對象 。也就是說, 非靜態方法只能在 所屬的類的對象上調用 。然而,一個靜態方法可以在類上調用 以及該類的一個對象。 A 靜態方法只能訪問靜態的 成員。一個非靜態方法可以訪問靜態和非靜態的 成員,因爲在調用靜態方法時,可能不會實例化類 (如果它是在類本身上調用的 )。在其他情況下,只有當類 已被實例化時,纔會調用非靜態方法 。一個靜態的 方法由 該類的所有實例共享。這些是基本的 的一些差異。我也想 在這方面指出一個經常被忽略的差異 。每當一種方法是在C++/Java/C#中調用的 ,參數('this'引用)的一個隱含的 是 與/不與其他 參數一起傳遞。如果使用靜態方法 調用,則'this'參考不是 ,因爲靜態方法屬於 類,因此沒有'this' 參考。

參考Static Vs Non-Static methods

1

基本區別在於非靜態成員是使用關鍵字「靜態」

所有靜態成員(包括變量和方法)與類名的幫助下簡稱同出聲明。 因此,類的靜態成員也被稱爲類參考成員或類成員..

爲了訪問類的非靜態成員,我們應該創建引用變量。 參考變量存儲對象..

+0

欲瞭解更多信息,你可以閱讀以下鏈接:http://stackoverflow.com/questions/1184701/static-vs-non-static-method http://stackoverflow.com/questions/1353309/java-static- vs-non-static-inner-class http://stackoverflow.com/questions/70324/java-inner-class-and-static-nested-class http://stackoverflow.com/questions/5241899/what-是最差之間靜電的方法-IN-A-非靜態級和靜電-m的 – Aamer 2012-10-03 05:44:56

3

靜態方法屬於類,非靜態方法屬於類的對象。 我給出了一個例子,它如何創建輸出之間的差異。

public class DifferenceBetweenStaticAndNonStatic { 

    static int count = 0; 
    private int count1 = 0; 

    public DifferenceBetweenStaticAndNonStatic(){ 
    count1 = count1+1; 
    } 

    public int getCount1() { 
    return count1; 
    } 

    public void setCount1(int count1) { 
    this.count1 = count1; 
    } 

    public static int countStaticPosition() { 
    count = count+1; 
    return count; 
    /* 
    * one can not use non static variables in static method.so if we will 
    * return count1 it will give compilation error. return count1; 
    */ 
    } 
} 

public class StaticNonStaticCheck { 

    public static void main(String[] args){ 
    for(int i=0;i<4;i++) { 
     DifferenceBetweenStaticAndNonStatic p =new DifferenceBetweenStaticAndNonStatic(); 
     System.out.println("static count position is " +DifferenceBetweenStaticAndNonStatic.count); 
     System.out.println("static count position is " +p.getCount1()); 
     System.out.println("static count position is " +DifferenceBetweenStaticAndNonStatic.countStaticPosition()); 

     System.out.println("next case: "); 
     System.out.println(" "); 

    } 
} 

}

現在輸出將:::

static count position is 0 
static count position is 1 
static count position is 1 
next case: 

static count position is 1 
static count position is 1 
static count position is 2 
next case: 

static count position is 2 
static count position is 1 
static count position is 3 
next case: 
22

靜態方法是,如果你只有一個實例(形勢,情況),您要使用的方法是有用,而且你不需要多個副本(對象)。例如,如果您正在編寫一種只記錄一個網站的方法,下載天氣數據,然後返回值,則可以將其編寫爲靜態,因爲您可以在方法中硬編碼所有必需的數據,並且你不會有多個實例或副本。然後,您可以訪問靜態使用下面的一個方法:使用

MyClass.myMethod(); 
this.myMethod(); 
myMethod(); 

非靜態方法,如果你要使用你的方法來創建多個副本。例如,如果您想要從波士頓,邁阿密和洛杉磯下載天氣數據,並且如果您可以從您的方法中進行此操作,而無需爲每個單獨位置單獨定製代碼,則可以非靜態方式訪問該方法:

MyClass boston = new MyClassConstructor(); 
boston.myMethod("bostonURL"); 

MyClass miami = new MyClassConstructor(); 
miami.myMethod("miamiURL"); 

MyClass losAngeles = new MyClassConstructor(); 
losAngeles.myMethod("losAngelesURL"); 

在上述例子中,爪哇創建從可以單獨地與「波士頓」訪問相同的方法三個單獨的對象和存儲位置,「邁阿密」,或「洛杉磯」參考。你不能訪問任何上述的靜態,因爲MyClass.myMethod();是該方法的通用引用,而不是非靜態引用創建的單個對象。

如果遇到訪問每個位置的方式或數據返回方式的情況有很大差異,那麼您無法在不跳過大量環的情況下編寫「一刀切」的方法,您可以通過編寫三個獨立的靜態方法來更好地實現您的目標,每個位置都有一個。

5

那麼,從技術上講,靜態方法和虛擬方法之間的差異就是鏈接的方式。

像大多數非OO語言一樣,傳統的「靜態」方法在編譯時「靜態地」鏈接/連接到它的實現。也就是說,如果在程序A中調用方法Y(),並將程序A與實現Y()的庫X鏈接起來,則X.Y()的地址將被硬編碼爲A,並且不能更改該地址。

在像JAVA這樣的OO語言中,「虛擬」方法在運行時解析爲「遲到」,並且您需要提供一個類的實例。因此,在程序A中,要調用虛擬方法Y(),您需要提供一個實例,例如B.Y()。在運行時,每次A呼叫B.Y()被調用的實現將取決於所使用的實例,所以B.Y(),C.Y()等......都可能在運行時提供不同的Y()實現。

爲什麼你會需要它?因爲這樣你可以將你的代碼與依賴關係解耦。例如,假設程序A正在執行「draw()」。使用靜態語言,就是這樣,但是使用OO,您將執行B.draw(),而實際繪圖將取決於對象B的類型,在運行時,它可以更改爲圓形等。這樣,您的代碼就可以即使在編寫代碼之後提供了新類型的B,也可以繪製多個事物而無需更改。漂亮 -

8

一般

靜態:不需要創建對象,我們可以直接調用使用

ClassName.methodname() 

非靜態:我們需要創建一個對象像

ClassName obj=new ClassName() 
obj.methodname(); 
2

如果你的方法與對象的特性有關,你應該定義它作爲非靜態方法。否則,您可以將您的方法定義爲靜態,並且可以獨立於對象使用它。

1

靜態方法的另一種場景。

是的,靜態方法是不屬於對象的類。當你不想讓任何人初始化這個類的對象,或者你不想要多個對象時,你需要使用私有構造函數等靜態方法。

在這裏,我們有私人的構造函數,並使用靜態方法創建一個對象。

例::

public class Demo { 

     private static Demo obj = null;   
     private Demo() { 
     } 

     public static Demo createObj() { 

      if(obj == null) { 
       obj = new Demo(); 
      } 
      return obj; 
     } 
} 

演示OBJ1 = Demo.createObj();

這裏,一次只有1個實例存活。

-1

「有時候,你想有一個適用於所有對象的變量這是用static修飾符完成

即類人 - 。磁頭數(1)是靜態的,同樣爲所有的人,然而人類的頭髮顏色對每個人來說都是可變的。

注意,靜態瓦爾也可用於跨所有實例共享信息

1

靜態方法例如

class StaticDemo 
{ 
public static void copyArg(String str1, String str2) 
{ 
    str2 = str1; 
    System.out.println("First String arg is: "+str1); 
    System.out.println("Second String arg is: "+str2); 
} 
public static void main(String agrs[]) 
{ 
    //StaticDemo.copyArg("XYZ", "ABC"); 
    copyArg("XYZ", "ABC"); 
} 
} 

輸出:

首先字符串arg是:XYZ

Second String arg是:XYZ

正如你在上面的例子中看到的,爲了調用靜態方法,我甚至沒有使用一個對象。它可以直接在程序中調用或使用類名稱。

非靜態方法例如

class Test 
{ 
public void display() 
{ 
    System.out.println("I'm non-static method"); 
} 
public static void main(String agrs[]) 
{ 
    Test obj=new Test(); 
    obj.display(); 
} 
} 

輸出:

我非靜態方法

非靜態方法總是通過使用類的對象被稱爲如上例所示。

要點:

如何調用靜態方法:直接或使用類名稱:

StaticDemo.copyArg(S1,S2); 或copyArg(s1,s2);

如何調用非靜態方法:使用類的對象:

測試OBJ =新測試();

1

簡而言之,從用戶的角度來看,靜態方法根本不使用任何變量,或者它使用的所有變量都是方法的局部變量,或者它們是靜態字段。將方法定義爲靜態可以帶來輕微的性能優勢。