我只是在阅读教科书中给我的课文,我不确定自己是否明白我在说什么。这基本上是在告诉我静态方法或类方法包括关键字“修饰符” static。但是我真的不知道这意味着什么?
有人可以用非常简单的术语向我解释什么是静态方法或类方法吗?
我还能简单地解释一下什么是实例方法吗?
这是他们在教科书中给我的:

是否存在静态修饰符具有重要的实际意义。一旦Java处理了它所属的类的定义,就可以调用并执行一个公共类方法。实例方法不是这种情况。在公共实例方法可以被调用和执行之前,必须创建它所属的类的实例。要使用公共类方法,您只需要类。另一方面,在使用公共实例方法之前,必须具有该类的实例。
在另一个方法的定义内调用静态方法的方式取决于这两个方法是否不同属于同一个阶级。在上面的示例中,阶乘和main都是MainClass类的方法。结果,在main的定义中对阶乘的调用仅引用方法名称“阶乘”。


#1 楼

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

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

评论


非常感谢您提供的看起来很熟悉的代码示例,现在我明白了

–潘茜
2012年8月16日18:36

@Rohan另一种看待它的好方法是,任何静态(类,方法或字段)都不真正属于任何东西,它只是出于组织目的而挂在类中。

– gobernador
2012年8月16日18:41

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

–user2416728
13年7月1日在6:17

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

–纳撒尼尔·福特(Nathaniel Ford)
2013年7月1日在16:24



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

–user2416728
13年7月2日在8:18

#2 楼

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

例如:

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


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

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


#3 楼

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

#4 楼

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


实例方法是需要在创建其类的对象之后才能对其进行调用的方法。静态方法是Java中可以在不创建类对象的情况下调用的方法。
静态方法使用static关键字声明。实例方法不能使用static关键字。
静态方法意味着它将作为类的单个副本存在。但是实例方法作为多个副本存在,具体取决于为该类创建的实例数量。
静态方法可以通过使用类引用来调用。实例或非静态方法通过使用对象引用来调用。
静态方法无法直接访问实例方法和实例变量。实例方法可以直接访问静态变量和静态方法。

参考:geeksforgeeks

#5 楼

实例方法=>在特定类的特定实例上调用。方法想知道在哪个类上调用了它。它发生的方式是一个称为“ this”的不可见参数。在“此”内部,我们已经为实例类的成员设置了值。 “这”不是变量。这是一个值,您无法更改它,并且该值是呼叫的接收者的参考。
例如:您调用fixmen(实例方法)来修复电视(实际程序)。他带有工具(“ this”参数)。他带有修理电视所需的特定工具,他还可以修理其他东西。
在静态方法中=>没有诸如“ this”之类的东西。
例如:同一修理工(静态方法)。当您打电话给他时,您必须指定要致电的维修人员(例如电工)。他只会来修理您的电视。但是,他没有解决其他问题的工具(没有'this'参数)。
静态方法通常对于不需要类实例中任何数据的操作很有用(from'this' '),并且只能使用其参数来实现其预期目的。

#6 楼

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

Myclass.get();


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

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


#7 楼

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

您要在没有实例的情况下调用方法。

如果仅适用于提供给它的参数。

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

#8 楼

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

这意味着每当创建实例或对象(使用new 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()将返回特定对象传递的数据总和。但是,如果有任何特定的实例或对象,则可以使用static方法从不独立的任何类中获取总和。因此,对于只需要工作参数的泛型方法,可以使其保持静态以使其保持DRY。

#9 楼

实例方法与静态方法


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

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


#10 楼

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