静态方法和非静态方法有什么区别?


68

请参见下面的代码段:

代码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作为答案输出。


3
在这里,“理解实例和类成员”对其进行了很好的解释。
Adeel Ansari

Answers:


154

静态方法属于类本身,而非静态(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();


Access指定符(公共)是否会影响静态方法访问?就像如果您的方法名称为静态字符串method1()会发生什么情况?
dinesh kandpal '17

也可以将该静态方法放在UtililyClass中吗?
karlihnos

31

如果只有一个要使用该方法的实例(情况,情况)并且不需要多个副本(对象),则静态方法很有用。例如,如果您正在编写一种方法,该方法可以登录到一个唯一的网站,然后下载天气数据,然后返回值,则可以将其编写为静态方法,因为您可以对方法中的所有必要数据进行硬编码,您将不会有多个实例或副本。然后,您可以使用以下任一方法静态访问该方法:

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(); 是对方法的通用引用,而不是对非静态引用创建的单个对象的引用。

如果您遇到访问每个位置的方式或返回数据的方式完全不同的情况,以至于无法编写出“千篇一律”的方法,而又不会遇到很多麻烦,那么您可以做得更好通过编写三种单独的静态方法来完成您的目标,每种方法一个。


有谁知道哪个是有效的?关于内存和空间?
Reejesh PK

12

通常

static:无需创建对象,我们可以使用直接调用

ClassName.methodname()

非静态的:我们需要创建一个像

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

8

静态方法属于类,非静态方法属于类的对象。也就是说,只能在其所属类的对象上调用非静态方法。但是,可以在类以及类的对象上调用静态方法。静态方法只能访问静态成员。非静态方法可以访问静态成员和非静态成员,因为在调用静态方法时,可能无法实例化该类(如果在类本身上调用了该类)。在其他情况下,仅当类已实​​例化时才能调用非静态方法。该类的所有实例都共享一个静态方法。这些是一些基本差异。我还要指出在这种情况下经常被忽略的差异。每当在C ++ / Java / C#中调用方法时,都会将隐式参数(“ this”引用)与/不与其他参数一起传递。如果是静态方法调用,则不会传递“ this”引用,因为静态方法属于一个类,因此没有“ this”引用。

参考静态与非静态方法


6

从技术上来讲,静态方法和虚拟方法之间的区别是链接的方式。

像大多数非OO语言一样,传统的“静态”方法在编译时就“静态地”链接至其实现。也就是说,如果您在程序A中调用方法Y(),并将程序A与实现X()的库X链接,则XY()的地址将被硬编码为A,并且您将无法更改它。

在像JAVA这样的OO语言中,“虚拟”方法在运行时“延迟”解析,您需要提供一个类的实例。因此,在程序A中,要调用虚拟方法Y(),您需要提供一个实例,例如BY()。在运行时,每次A调用BY()时,所调用的实现将取决于所使用的实例,因此BY(),CY()等...都可能在运行时提供Y()的不同实现。

您为什么会需要它?因为这样可以将代码与依赖项分离。例如,假设程序A正在执行“ draw()”。使用静态语言就可以了,但是使用OO时,您将执行B.draw(),而实际绘制将取决于对象B的类型,在运行时可以更改为正方形等。这样,您的代码可以即使在编写代码后提供了新的B类型,也无需更改即可绘制多个内容。漂亮-


4

静态方法属于类,非静态方法属于类的对象。我举一个例子,说明如何在输出之间产生差异。

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:  

3

如果您的方法与对象的特性有关,则应将其定义为非静态方法。否则,您可以将方法定义为静态,并且可以独立于对象使用。


3

静态方法示例

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

2

基本区别是非静态成员是使用关键字'static'声明的

所有静态成员(变量和方法)均在类名的帮助下进行引用。因此,类的静态成员也称为类引用成员或类成员。

为了访问类的非静态成员,我们应该创建引用变量。参考变量存储一个对象。



2

简而言之,从用户的角度来看,静态方法要么根本不使用任何变量,要么使用的所有变量都是该方法的局部变量,或者它们是静态字段。将方法定义为静态会带来一点性能上的好处。


2

静态方法的另一种情况。

是的,静态方法属于该类,而不属于该对象。当您不希望任何人初始化该类的对象或不希望有多个对象时,则需要使用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个实例在世。


0
- 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 

0

有时,您希望拥有所有对象共有的变量。这可以通过static修饰符完成。

例如,人类类别-头数(1)是静态的,对于所有人类而言都是相同的,但是人类-头发的颜色对于每个人类而言都是可变的。

请注意,静态变量也可以用于在所有实例之间共享信息

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.