静态与实例变量:差异?

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

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

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

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

 private static int sharedAttribute; 

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

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

  1. 类常量:因为它们是const ,所有类访问相同的值都不会有害,因为没有人可以改变它。 如果你有很多类的实例,他们也可以节省内存。 但是不确定并发访问。
  2. 要共享的变量,例如引用计数器和公司。

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

static方法只能访问static属性,但在尝试之前请三思而后行。

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

假设有一个测试类:

 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(); 

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

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

在这两种情况下,输出将是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; 

希望能解释您的疑问。

实例变量

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

 public class Product { public int barcode; } 

类变量

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

 public class Product { public static int barcode; } 

完整示例:

实例变量

 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; } 

输出将是:

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; } } 

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

987654
987654

类变量只有一个由类的所有不同对象共享的副本,而每个对象都有自己的实例变量的个人副本。 因此,跨不同对象的实例变量可以具有不同的值,而跨不同对象的类变量只能有一个值。

静态(类)变量和实例变量都是成员变量,因为它们都与特定的类相关联,但它们之间的区别是类变量只有一个副本由类的所有不同对象共享,而每个对象都有它是实例变量的个人副本。 因此,跨不同对象的实例变量可以具有不同的值,而跨不同对象的类变量只能有一个值。

实例变量包含必须由多个方法,构造函数或块引用的值,或者必须在整个类中存在的对象状态的基本部分。 静态变量只是每个类的每个类变量的一个副本,无论从中创建多少个对象。

我想你正在考虑静态关键字的C / C ++定义。 在那里,static关键字有很多用途。 在Java中,您的post中描述了static关键字的function。 无论如何,你可以自己尝试一下:

 public class Test_Static{ static int x; public static void main(String[] argv){ Test_Static a = new Test_Static(); Test_Static b = new Test_Static(); ax = 1; // This will give an error, but still compile. bx = 2; System.out.println(ax); // Should print 2 } } 

对于非静态变量也类似:

 public class Test_NonStatic{ int x; public static void main(String [] argv){ Test_NonStatic a = new Test_NonStatic(); Test_NonStatic b = new Test_NonStatic(); ax = 1; bx = 2; System.out.println(ax); // Should print 1. } } 

考虑一个MyClass类,它有一个静态成员和一个非静态成员:

 public class MyClass { public static int STATICVARIABLE = 0; public int nonStaticVariable = 0; } 

现在,让我们创建一个main()来创建几个实例:

 public class AnotherClass{ public static void main(String[] args) { // Create two instances of MyClass MyClass obj1 = new MyClass(); MyClass obj2 = new MyClass(); obj1.nonStaticVariable = 30; // Setting value for nonstatic varibale obj1.STATICVARIABLE = 40; //Setting value for static variable obj2.nonStaticVariable = 50; obj2.STATICVARIABLE = 60; // Print the values actually set for static and non-static variables. System.out.println(obj1.STATICVARIABLE); System.out.println(obj1.nonStaticVariable); System.out.println(obj2.STATICVARIABLE); System.out.println(obj2.nonStaticVariable); } } 

结果:

 60 30 60 50 

现在你可以看到静态变量的值两次打印60 ,因为obj1obj2都指的是同一个变量。 使用非静态变量,输出不同,因为创建时每个对象都保留其自己的非静态变量副本; 对它们所做的更改不会影响另一个对象创建的变量的另一个副本。