关于java:静态方法和非静态方法有什么区别?

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

请参见下面的代码段:

代码1

1
2
3
4
5
6
7
8
9
10
11
12
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

1
2
3
4
5
6
7
8
9
10
11
12
13
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作为答案。


静态方法属于类本身,而非静态(又称实例)方法属于从该类生成的每个对象。如果您的方法做了一些不依赖于类的个别特性的事情,那么将其设为静态的(它将使程序的占地面积更小)。否则,它应该是非静态的。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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()。如果用方法2尝试,它将失败。但这是可行的:Foo bar = new Foo(1); bar.method2();


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

1
2
3
MyClass.myMethod();
this.myMethod();
myMethod();

如果要使用方法创建多个副本,则使用非静态方法。例如,如果您想从波士顿、迈阿密和洛杉矶下载天气数据,并且您可以从方法中下载,而不必为每个单独的位置单独定制代码,那么您可以非静态地访问该方法:

1
2
3
4
5
6
7
8
MyClass boston = new MyClassConstructor();
boston.myMethod("bostonURL");

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

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

在上面的示例中,Java创建了三个独立的对象和内存位置,这些方法和方法可以单独访问"波士顿"、"迈阿密"或"洛杉矶"引用。您不能静态地访问上面的任何内容,因为myClass.myMethod();是对方法的一般引用,而不是对非静态引用创建的单个对象的引用。

如果遇到这样一种情况,即访问每个位置的方式或返回数据的方式完全不同,以至于在不跳过许多圈的情况下无法编写"一刀切"的方法,那么您可以通过编写三个单独的静态方法(每个位置一个)来更好地实现目标。


一般来说

静态:不需要创建我们可以直接使用

1
ClassName.methodname()

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

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

A static method belongs to the class
and a non-static method belongs to an
object of a class. That is, a
non-static method can only be called
on an object of a class that it
belongs to. A static method can
however be called both on the class as
well as an object of the class. A
static method can access only static
members. A non-static method can
access both static and non-static
members because at the time when the
static method is called, the class
might not be instantiated (if it is
called on the class itself). In the
other case, a non-static method can
only be called when the class has
already been instantiated. A static
method is shared by all instances of
the class. These are some of the basic
differences. I would also like to
point out an often ignored difference
in this context. Whenever a method is
called in C++/Java/C#, an implicit
argument (the 'this' reference) is
passed along with/without the other
parameters. In case of a static method
call, the 'this' reference is not
passed as static methods belong to a
class and hence do not have the 'this'
reference.

参考:静态与非静态方法


好吧,从技术上讲,静态方法和虚拟方法的区别在于它们的链接方式。

像大多数非OO语言中一样,传统的"静态"方法在编译时"静态地"链接/连接到其实现。也就是说,如果在程序A中调用方法y(),并将程序a与实现y()的库x链接,则x.y()的地址将硬编码到a,并且不能更改该地址。

在像Java这样的OO语言中,"虚拟"方法在运行时被"迟"解析,并且需要提供一个类的实例。因此,在程序A中,要调用虚方法y(),您需要提供一个实例,例如b.y()。在运行时,每次调用b.y()时,调用的实现将取决于所使用的实例,因此b.y()、c.y()等…在运行时,所有可能提供y()的不同实现。

为什么你会需要它?因为这样可以将代码与依赖项分离。例如,假设程序A正在执行"draw()"。对于静态语言,就是这样,但是对于OO,您将执行b.draw(),实际的绘图将取决于对象b的类型,对象b在运行时可以变为正方形、圆形等。这样,您的代码可以绘制多个不需要更改的东西,即使在编写代码后提供了新的类型b。俏皮的


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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("");

    }
}

}

现在输出为:::

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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:


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


简单地说,从用户的角度来看,静态方法要么根本不使用变量,要么它使用的所有变量都是该方法的局部变量,要么它们是静态字段。将一个方法定义为静态方法会带来轻微的性能优势。


静态方法示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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");
    }
}

输出:

1
2
3
First String arg is: XYZ

Second String arg is: XYZ

正如您在上面的示例中看到的,对于调用静态方法,我甚至没有使用对象。它可以在程序中直接调用,也可以使用类名。

非静态方法示例

1
2
3
4
5
6
7
8
9
10
11
12
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();
    }
}

输出:

1
I'm non-static method

非静态方法总是通过使用类的对象来调用,如上面的示例所示。

要点:

如何调用静态方法:直接或使用类名:

1
StaticDemo.copyArg(s1, s2);

1
copyArg(s1, s2);

如何调用非静态方法:使用类的对象:

1
Test obj = new Test();

静态方法的另一个场景。

Yes, Static method is of the class not of the object. And when you don't want anyone to initialize the object of the class or you don't want more than one object, you need to use Private constructor and so the static method.

这里,我们有一个私有的构造函数,使用静态方法创建一个对象。

前任::

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Demo {

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

        public static Demo createObj() {

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

Demo obj1 = Demo.createObj();

在这里,一次只有一个实例是活动的。


基本区别是非静态成员使用out声明,使用关键字"static"

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

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
- 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

有时,您希望拥有所有对象都通用的变量。这是通过静态修改器完成的。

也就是说,类人——头的数量(1)是静态的,对于所有人来说都是相同的,但是每个人的头发颜色是可变的。

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