簡體   English   中英

靜態方法和非靜態方法有什么區別?

[英]What is the difference between a static method and a non-static method?

請參見下面的代碼段:

代碼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作為答案。

靜態方法屬於該類本身,而非靜態(aka實例)方法屬於從該類生成的每個對象。 如果您的方法執行的操作不依賴於其類的單個特征,請將其設為靜態(這將使程序的占用空間減小)。 否則,它應該是非靜態的。

例:

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(); Foo bar = new Foo(1); bar.method2();

如果只有一個要使用該方法的實例(情況,情況),並且不需要多個副本(對象),則靜態方法很有用。 例如,如果您正在編寫一種方法,該方法可以登錄到一個唯一的網站,然后下載天氣數據,然后返回值,則可以將其編寫為靜態方法,因為您可以對方法中的所有必要數據進行硬編碼,並且您將不會有多個實例或副本。 然后,您可以使用以下任一方法靜態訪問該方法:

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");

在上面的示例中,Java使用可以使用“波士頓”,“邁阿密”或“ losAngeles”引用分別訪問的同一方法創建三個單獨的對象和內存位置。 您不能靜態訪問上述任何內容,因為MyClass.myMethod(); 是對方法的通用引用,而不是對非靜態引用創建的單個對象的引用。

如果您遇到訪問每個位置的方式或返回數據的方式完全不同的情況,以至於無法跳過很多麻煩就無法編寫“一刀切”的方法通過編寫三種單獨的靜態方法來實現您的目標,每種方法一個。

通常

static :無需創建對象,我們可以使用直接調用

ClassName.methodname()

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

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

靜態方法屬於類,非靜態方法屬於類的對象。 也就是說,只能在其所屬類的對象上調用非靜態方法。 但是,可以在類以及類的對象上調用靜態方法。 靜態方法只能訪問靜態成員。 非靜態方法可以訪問靜態成員和非靜態成員,因為在調用靜態方法時,可能無法實例化該類(如果在類本身上調用了該類)。 在另一種情況下,僅當類已實​​例化時才能調用非靜態方法。 該類的所有實例都共享一個靜態方法。 這些是一些基本差異。 我還要指出在這種情況下經常被忽略的差異。 每當在C ++ / Java / C#中調用方法時,都會將隱式參數(“ this”引用)與/不與其他參數一起傳遞。 如果是靜態方法調用,則不會傳遞“ this”引用,因為靜態方法屬於一個類,因此沒有“ this”引用。

參考靜態與非靜態方法

從技術上來講,靜態方法和虛擬方法之間的區別是鏈接的方式。

像大多數非OO語言一樣,傳統的“靜態”方法在編譯時就“靜態地”鏈接至其實現。 即,如果您在程序A中調用方法Y(),並將程序A與實現Y()的庫X鏈接,則XY()的地址將被硬編碼為A,並且您將無法更改它。

在像JAVA這樣的OO語言中,“虛擬”方法在運行時“延遲”解析,您需要提供一個類的實例。 因此,在程序A中,要調用虛擬方法Y(),您需要提供一個實例,例如BY()。 在運行時,每次A調用BY()時,所調用的實現將取決於所使用的實例,因此BY(),CY()等...都可能在運行時提供Y()的不同實現。

您為什么會需要它? 因為這樣可以將代碼與依賴項分離。 例如,假設程序A正在執行“ draw()”。 使用靜態語言就可以了,但是使用OO時,您將執行B.draw(),而實際的繪制將取決於對象B的類型,在運行時可以更改為正方形等。這樣,您的代碼就可以即使在編寫代碼后提供了新的B類型,也無需更改即可繪制多個內容。 漂亮-

靜態方法屬於類,非靜態方法屬於類的對象。 我舉一個例子,說明如何在輸出之間產生差異。

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:  

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

靜態方法示例

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");
    }
}

輸出:

First String arg is: XYZ

Second String arg is: 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();
    }
}

輸出:

I'm non-static method

如上例所示,總是通過使用class對象來調用非靜態方法。

關鍵點:

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

StaticDemo.copyArg(s1, s2);

要么

copyArg(s1, s2);

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

Test obj = new Test();

基本區別是非靜態成員是使用關鍵字'static'聲明的

所有靜態成員(變量和方法)都在類名的幫助下進行引用。 因此,類的靜態成員也稱為類引用成員或類成員。

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

靜態方法的另一種情況。

是的,靜態方法屬於該類,而不屬於該對象。 並且當您不希望任何人初始化類的對象或不希望有多個對象時,您需要使用Private構造函數以及靜態方法。

在這里,我們有私有構造函數,並使用靜態方法來創建對象。

例如:

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個實例在世。

簡而言之,從用戶的角度來看,靜態方法要么根本不使用任何變量,要么使用的所有變量都是該方法的局部變量,或者它們是靜態字段。 將方法定義為靜態會帶來一點性能上的好處。

有時,您希望擁有所有對象共有的變量。 這可以通過static修飾符完成。

例如,人類類別-頭數(1)是靜態的,對於所有人類而言都是相同的,但是人類-頭發的顏色對於每個人類而言都是可變的。

注意,靜態變量也可以用於在所有實例之間共享信息

- First we must know that the diff bet static and non static methods 
is differ from static and non static variables : 

- this code explain static method - non static method and what is the diff 

    public class MyClass {
        static {
            System.out.println("this is static routine ... ");

        }
          public static void foo(){
            System.out.println("this is static method ");
        }

        public void blabla(){

         System.out.println("this is non static method ");
        }

        public static void main(String[] args) {

           /* ***************************************************************************  
            * 1- in static method you can implement the method inside its class like :  *       
            * you don't have to make an object of this class to implement this method   *      
            * MyClass.foo();          // this is correct                                *     
            * MyClass.blabla();       // this is not correct because any non static     *
            * method you must make an object from the class to access it like this :    *            
            * MyClass m = new MyClass();                                                *     
            * m.blabla();                                                               *    
            * ***************************************************************************/

            // access static method without make an object 
            MyClass.foo();

            MyClass m = new MyClass();
            // access non static method via make object 
            m.blabla();
            /* 
              access static method make a warning but the code run ok 
               because you don't have to make an object from MyClass 
               you can easily call it MyClass.foo(); 
            */
            m.foo();
        }    
    }
    /* output of the code */
    /*
    this is static routine ... 
    this is static method 
    this is non static method 
    this is static method
    */

 - this code explain static method - non static Variables and what is the diff 


     public class Myclass2 {

                // you can declare static variable here : 
                // or you can write  int callCount = 0; 
                // make the same thing 
                //static int callCount = 0; = int callCount = 0;
                static int callCount = 0;    

                public void method() {
                    /********************************************************************* 
                    Can i declare a static variable inside static member function in Java?
                    - no you can't 
                    static int callCount = 0;  // error                                                   
                    ***********************************************************************/
                /* static variable */
                callCount++;
                System.out.println("Calls in method (1) : " + callCount);
                }

                public void method2() {
                int callCount2 = 0 ; 
                /* non static variable */   
                callCount2++;
                System.out.println("Calls in method (2) : " + callCount2);
                }


            public static void main(String[] args) {
             Myclass2 m = new Myclass2();
             /* method (1) calls */
             m.method(); 
             m.method();
             m.method();
             /* method (2) calls */
             m.method2();
             m.method2();
             m.method2();
            }

        }
        // output 

        // Calls in method (1) : 1
        // Calls in method (1) : 2
        // Calls in method (1) : 3
        // Calls in method (2) : 1
        // Calls in method (2) : 1
        // Calls in method (2) : 1 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM