静态与实例变量:差异?

20 java class instance-variables static-variables

静态变量和实例变量之间有什么区别.以下句子是我无法得到的:

在某些情况下,类的所有对象只应共享特定变量的一个副本 - 这里使用静态变量.
静态变量表示类范围信息.类的所有对象共享相同的数据.

我认为实例变量是使用类宽,而静态变量只在自己的方法中有范围?

Ste*_*ppo 25

在类属性的上下文中,static具有不同的含义.如果你有一个像这样的字段:

private static int sharedAttribute;
Run Code Online (Sandbox Code Playgroud)

然后,该类的每个实例将共享相同的变量,因此,如果您在一个实例中更改它,则更改将反映在更改之前或之后创建的所有实例中.

如上所述,您可能会理解在许多情况下这很糟糕,因为它很容易变成不希望的副作用:更改对象a也会影响b,您可能最终想知道为什么b更改没有明显的原因.无论如何,有些情况下这种行为是绝对可取的:

  1. 类常量:因为它们是const,所有类访问相同的值都不会有害,因为没有人可以改变它.如果你有很多类的实例,他们也可以节省内存.但是不确定并发访问.
  2. 被变量旨在被共享,如参考计数器&CO.

staticvars在程序启动之前被实例化,所以如果你有太多的vars,你可能会减慢启动速度.

一个static方法只能访问static属性,而是试图在此之前三思而后行.

经验法则:不要使用static,除非有必要,你知道你在做什么,或者你宣布一个类不变.

  • 谢谢,所以如果声明一个静态变量,只有当我有兴趣能够更改该类的每个对象的所有值时,我才会这样做,例如,如果我为员工声明了一个静态变量,我就可以更新所有员工都通过执行类似于employee.rate_of_pay 的操作来支付工资? (2认同)
  • 确切地。显然,该更改只会影响其后发生的操作。因此,如果您想在更改费率后重新计算工资,则必须在更改后调用“recalculateWage()”或类似方法。 (2认同)

小智 11

假设有一个测试类:

class Test{
public static int a = 5;
public int b = 10;
}
// here t1 and t2 will have a separate copy of b
// while they will have same copy of a.
Test t1 = new test(); 
Test t2 = new test();
Run Code Online (Sandbox Code Playgroud)

您可以使用它的类名称来访问静态变量

Test.a = 1//some value But you can not access instance variable like this
System.out.println(t1.a);
System.out.println(t2.a);
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,输出将为1作为测试类的所有实例的共享.而实例变量将各自具有b(实例变量)的单独副本

 t1.b = 15 // will not be reflected in t2.
 System.out.println(t1.b); // this will print 15
 System.out.println(t2.b); / this will still print 10; 
Run Code Online (Sandbox Code Playgroud)

希望能解释您的疑问.


小智 9

实例变量

这些变量属于类的实例,因此属于对象。该类(对象)的每个实例都具有该变量的副本。对变量所做的更改不会反映在该类的其他实例中。

public class Product {
    public int barcode;
}
Run Code Online (Sandbox Code Playgroud)

类变量

这些也称为静态成员变量,并且该变量只有一个副本与该类的所有实例共享。如果对该变量进行了更改,则所有其他实例将看到更改的效果。

public class Product {
    public static int barcode;
}
Run Code Online (Sandbox Code Playgroud)

完整示例:

实例变量

public class Main {
    public static void main(String[] args) {

        Product prod1 = new Product();
        prod1.barcode = 123456;

        Product prod2 = new Product();
        prod2.barcode = 987654;

        System.out.println(prod1.barcode);
        System.out.println(prod2.barcode);
    }
}

public class Product {
    public int barcode;
}
Run Code Online (Sandbox Code Playgroud)

输出将是:

123456
987654

现在,通过使其变为静态将实例变量更改为类变量:

类变量

public class Main {
    public static void main(String[] args) {

        Product prod1 = new Product();
        prod1.setBarcode(123456);
        Product prod2 = new Product();
        prod2.setBarcode(987654);

        System.out.println(prod1.getBarcode());
        System.out.println(prod2.getBarcode());
    }
}

public class Product {
    public static int barcode;

    public int getBarcode() {
        return barcode;
    }

    public void setBarcode(int value){
        barcode = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用非静态方法来获取和设置Barcode的值,以便能够从对象而不是从类中调用它。
输出如下:

987654
987654