【问题标题】:What is the difference between a static method and a non-static method?静态方法和非静态方法有什么区别?
【发布时间】:2011-04-23 15:27:27
【问题描述】:

见下面的代码sn-ps:

代码 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));
    }
}

这些代码sn-ps有什么区别?两者都输出15 作为答案。

【问题讨论】:

标签: java


【解决方案1】:

静态方法属于类本身,非静态(又名实例)方法属于从该类生成的每个对象。如果您的方法所做的事情不依赖于其类的个别特征,请将其设为静态(这将使程序的占用空间更小)。否则,它应该是非静态的。

例子:

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

【讨论】:

  • 访问说明符(公共)是否影响静态方法访问?如果你的方法名是静态字符串 method1() 会发生什么?
  • 是否也可以将该静态方法放入 UtililyClass 中?
【解决方案2】:

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

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 从同一个方法创建了三个独立的对象和内存位置,您可以使用“boston”、“miami”或“losAngeles”引用单独访问这些对象和内存位置。您无法静态访问上述任何内容,因为 MyClass.myMethod();是对方法的通用引用,而不是对非静态引用创建的单个对象的引用。

如果您遇到这样一种情况,即您访问每个位置的方式或返回数据的方式非常不同,以至于您无法编写“一刀切”的方法而不跳过很多环节,您可以通过编写三个单独的静态方法来更好地实现您的目标,每个位置一个。

【讨论】:

  • 有谁知道哪一种效率高?说到内存和空间?
【解决方案3】:

一般

静态:不需要创建我们可以直接调用的对象

ClassName.methodname()

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

的对象
ClassName obj=new ClassName()
obj.methodname();

【讨论】:

    【解决方案4】:

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

    参考Static Vs Non-Static methods

    【讨论】:

      【解决方案5】:

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

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

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

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

      【讨论】:

        【解决方案6】:

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

        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:  
        

        【讨论】:

          【解决方案7】:

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

          【讨论】:

            【解决方案8】:

            静态方法示例

            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
            

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

            要点:

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

            StaticDemo.copyArg(s1, s2);
            

            copyArg(s1, s2);
            

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

            Test obj = new Test();
            

            【讨论】:

              【解决方案9】:

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

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

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

              【解决方案10】:

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

              【讨论】:

                【解决方案11】:

                静态方法的另一种场景。

                是的,静态方法属于类而不属于对象。而当你不想让任何人初始化类的对象或者你不想要多个对象时,你需要使用私有构造函数等静态方法。

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

                例如::

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

                在这里,一次只有 1 个实例处于活动状态。

                【讨论】:

                  【解决方案12】:
                  - 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 
                  

                  【讨论】:

                    【解决方案13】:

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

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

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

                    【讨论】:

                      猜你喜欢
                      • 2011-07-11
                      • 1970-01-01
                      • 1970-01-01
                      • 2013-07-21
                      • 2012-11-02
                      • 2011-01-27
                      • 1970-01-01
                      • 1970-01-01
                      • 2011-06-18
                      相关资源
                      最近更新 更多