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

Sum*_*hra 66 java

请参阅下面的代码段:

代码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));
    }
}
Run Code Online (Sandbox Code Playgroud)

代码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));
    }
}
Run Code Online (Sandbox Code Playgroud)

这些代码片段有什么区别?两者都15作为答案输出.

Sap*_*Sun 144

静态方法属于类本身,非静态(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
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以调用这样的静态方法:Foo.method1().如果您尝试使用method2,它将失败.但这会奏效:Foo bar = new Foo(1); bar.method2();


Vik*_*len 29

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

MyClass.myMethod();
this.myMethod();
myMethod();
Run Code Online (Sandbox Code Playgroud)

如果您要使用您的方法创建多个副本,则使用非静态方法.例如,如果要从波士顿,迈阿密和洛杉矶下载天气数据,并且如果您可以在方法中执行此操作而无需为每个单独的位置单独自定义代码,则可以非静态地访问该方法:

MyClass boston = new MyClassConstructor(); 
boston.myMethod("bostonURL");

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

MyClass losAngeles = new MyClassConstructor();
losAngeles.myMethod("losAngelesURL");
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,Java使用相同的方法创建三个单独的对象和内存位置,您可以使用"boston","miami"或"losAngeles"引用单独访问这些对象.你无法静态访问上述任何内容,因为MyClass.myMethod(); 是对方法的通用引用,而不是非静态引用创建的单个对象.

如果你遇到一种情况,你访问每个位置的方式,或数据的返回方式,是不同的,你不能写一个"一刀切"的方法,而不是跳过很多箍,你可以更好通过编写三个独立的静态方法来实现您的目标,每个位置一个.


mur*_*a k 12

通常

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

ClassName.methodname()
Run Code Online (Sandbox Code Playgroud)

非静态:我们需要创建一个像这样的对象

ClassName obj=new ClassName()
obj.methodname();
Run Code Online (Sandbox Code Playgroud)


Emi*_*mil 8

静态方法属于类,非静态方法属于类的对象.也就是说,只能在它所属的类的对象上调用非静态方法.但是,静态方法既可以在类上调用,也可以在类的对象上调用.静态方法只能访问静态成员.非静态方法可以访问静态和非静态成员,因为在调用静态方法时,可能不会实例化类(如果在类本身上调用它).在另一种情况下,只有在已经实例化类时才能调用非静态方法.静态方法由类的所有实例共享.这些是一些基本的差异.我还想指出在这种背景下经常被忽视的差异.每当在C++/Java/C#中调用一个方法时,一个隐式参数('this'引用)与/不带其他参数一起传递.在静态方法调用的情况下,'this'引用不会传递,因为静态方法属于一个类,因此没有'this'引用.

参考:静态Vs非静态方法


Ale*_*Vaz 6

从技术上讲,静态方法和虚方法之间的区别在于链接的方式.

像大多数非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,也无需更改即可绘制多个内容.漂亮 -