2010-10-11 288 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

简而言之,从用户的角度来看,静态方法根本不使用任何变量,或者它使用的所有变量都是方法的局部变量,或者它们是静态字段。将方法定义为静态可以带来轻微的性能优势。