静态方法和实例方法之间的区别


88

我只是在阅读教科书中给我的课文,但我不确定自己是否明白我在说什么。这基本上是在告诉我静态方法或类方法包括static的“ modifier”关键字。但是我真的不知道那意味着什么吗?

有人可以简单地向我解释什么是静态方法或类方法吗?

另外,我可以简单解释一下什么是Instance方法吗?

这是他们在教科书中给我的:

存在或不存在静态修饰符具有重要的实际意义。一旦Java处理了它所属的类的定义,就可以调用并执行一个公共类方法。实例方法不是这种情况。在公共实例方法可以被调用和执行之前,必须创建它所属的类的实例。要使用公共类方法,您只需要类。另一方面,在使用公共实例方法之前,您必须具有该类的实例。

在另一个方法的定义内调用静态方法的方式根据这两个方法是否属于同一类而有所不同。在上面的示例中,阶乘和main都是MainClass类的方法。结果,在main的定义中对阶乘的调用仅引用方法名称“阶乘”。

Answers:


161

Java的基本范例是您编写类,并将这些类实例化。实例化的对象(类的实例)具有与它们相关联的属性(成员变量),这些属性会影响它们的行为;当实例执行其方法时,它将引用这些变量。

但是,所有特定类型的对象可能都具有完全不依赖于成员变量的行为。这些方法最好设为静态。由于是静态的,因此不需要类的实例即可运行该方法。

您可以执行以下操作来执行静态方法:

MyClass.staticMethod();//Simply refers to the class's static code

但是要执行非静态方法,您必须执行以下操作:

MyClass obj = new MyClass();//Create an instance
obj.nonstaticMethod();//Refer to the instance's class's code

在更深层次上,当编译器将一个类放在一起时,它包含一些指向方法的指针。当执行这些方法时,它将跟随指针并在远端执行代码。如果实例化了一个类,则创建的对象将包含一个指向“虚拟方法表”的指针,该指针指向继承层次结构中该特定类要调用的方法。但是,如果该方法是静态的,则不需要“虚拟方法表”:对该方法的所有调用都将进入内存中的确切位置,以执行完全相同的代码。因此,在高性能系统中,如果您不依赖实例变量,则最好使用静态方法。


2
非常感谢您提供它们看起来熟悉的代码示例,所以我现在明白了
Panthy 2012年

4
@Rohan另一个看待它的好方法是,任何事物static(类,方法或字段)实际上都不属于任何事物,它只是出于组织目的而挂在类中。
gobernador

1
此外,静态字段还用作数据对象(其中一个保存数据,因此不能更改,但您可以在其中操作数据。)。静态方法只能在静态字段上调用,并且此后始终保持不变或不变。还是不实例化!
user2416728

1
@ user2416728您的评论非常困惑。可以更改静态字段,但是它们的范围对于其执行环境是全局的。因此,任何有权访问该字段的代码都可以访问同一数据。这不等于该数据保持不变(除非使用“ final”修饰符)。
纳撒尼尔·福特

2
是的,“不变” >>我的意思是无法实例化!
user2416728

19

未声明为静态的方法和变量称为实例方法和实例变量。要引用实例方法和变量,必须首先实例化该类,这意味着您应该首先创建该类的对象。对于静态实例,您无需实例化该类,您可以使用带有句点符号的类名来访问方法和变量在(。)中

例如:

Person.staticMethod();           //accessing static method.

对于非静态方法,您必须实例化该类。

Person person1 = new Person();   //instantiating
person1.nonStaticMethod();       //accessing non-static method.

8

静态方法,变量属于整个类,而不仅仅是对象实例。静态方法变量与整个类相关联,而不是与类的特定实例相关联。每个对象将共享静态方法,变量的通用副本。每个类只有一个副本,无论从其中创建了多少个对象。


8

静态方法和实例方法之间的区别

  1. 实例方法是需要先创建其类的对象才能调用的方法。静态方法是Java中可以在不创建类对象的情况下调用的方法。

  2. 静态方法用static关键字声明。实例方法不带有static关键字。

  3. 静态方法意味着它将作为类的单个副本存在。但是实例方法作为多个副本存在,具体取决于为该类创建的实例数量。

  4. 静态方法可以通过使用类引用来调用。实例或非静态方法通过使用对象引用来调用。

  5. 静态方法不能直接访问实例方法和实例变量。实例方法可以直接访问静态变量和静态方法。

参考:geeksforgeeks


4

实例方法=>在特定类的特定实例上调用。方法想知道在哪个类上调用了它。它发生的方式是一个称为“ this”的不可见参数。在“此”内部,我们已经为实例类的成员设置了值。“这”不是变量。这是一个值,您无法更改它,该值是呼叫接收方的参考。 例如:您致电维修员(实例方法)修复电视(实际程序)。他带有工具(“ this”参数)。他带有修复电视所需的特定工具,并且还可以修复其他东西。

静态方法=>中,没有“ this”这样的东西。 例如:同一位修理工(静态方法)。当您打电话给他时,您必须指定要致电的维修人员(例如电工)。他只会来修理您的电视。但是,他没有解决其他问题的工具(没有“ this”参数)。

静态方法通常对不需要类实例(来自“ this”)中任何数据的操作很有用,并且仅使用其参数即可执行其预期的目的。


2

对象的行为取决于该类的变量和方法。当我们创建一个类时,我们为其创建一个对象。对于静态方法,我们不需要它们,因为静态方法意味着所有对象都将具有相同的副本,因此不需要对象。例如:

Myclass.get();

在实例方法中,每个对象将具有不同的行为,因此它们必须使用对象实例来调用该方法。例如:

Myclass x = new Myclass();
x.get();

1

如果不应更改方法的状态或不使用任何实例变量。

您要调用没有实例的方法。

如果仅对提供给它的参数起作用。

实用程序功能是静态方法的良好实例。即math.pow(),此函数不会更改不同值的状态。所以它是静态的。


1

简而言之,静态方法和静态变量是类级别,而实例方法和实例变量则是实例或对象级别。

这意味着无论何时创建实例或对象(使用新的ClassName()),该对象都将保留其自己的instace变量副本。如果您有五个相同类的对象,那么实例变量将有五个不同的副本。但是,这五个对象的静态变量和方法都相同。如果需要每个创建的对象都可以使用的通用属性,请将其静态化。如果需要不需要对象特定数据才能工作的方法,请使其为静态。静态方法仅适用于静态变量,或者将基于传递的参数返回数据。

class A {
    int a;
    int b;

    public void setParameters(int a, int b){
        this.a = a;
        this.b = b;
    }
    public int add(){
        return this.a + this.b;
   }

    public static returnSum(int s1, int s2){
        return (s1 + s2);
    }
}

在上面的示例中,当您将add()调用为:

A objA = new A();
objA.setParameters(1,2); //since it is instance method, call it using object
objA.add(); // returns 3 

B objB = new B();
objB.setParameters(3,2);
objB.add(); // returns 5

//calling static method
// since it is a class level method, you can call it using class itself
A.returnSum(4,6); //returns 10

class B{
    int s=8;
    int t = 8;
    public addition(int s,int t){
       A.returnSum(s,t);//returns 16
    }
}

在第一类中,add()将返回特定对象传递的数据总和。但是静态方法可用于从任何非独立类(如果有任何特定实例或对象)获取总和。因此,对于只需要工作参数的通用方法,可以使其保持静态以使其保持DRY状态。


0

实例方法与静态方法

  1. 实例方法可以直接访问实例方法和实例变量。

  2. 实例方法可以直接访问静态变量和静态方法。

  3. 静态方法可以直接访问静态变量和静态方法。

  4. 静态方法不能直接访问实例方法和实例变量。他们必须使用对对象的引用。静态方法不能使用此关键字,因为没有实例可以引用“ this”。


-2

静态修饰符放在函数前面时,意味着该函数仅存在一个副本。如果静态修饰符未放置在函数的前面,则对于该类的每个对象或实例,都会创建该函数的新副本。:)变量也是如此。

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.