Java 静态变量与实例变量:区别?
静态变量和实例变量之间的区别是什么。下面这句话是我无法理解的: 在某些情况下,一个类的所有对象只能共享一个特定变量的副本-这里使用的是一个静态变量。Java 静态变量与实例变量:区别?,java,class,instance-variables,static-variables,Java,Class,Instance Variables,Static Variables,静态变量和实例变量之间的区别是什么。下面这句话是我无法理解的: 在某些情况下,一个类的所有对象只能共享一个特定变量的副本-这里使用的是一个静态变量。 静态变量表示类范围的信息。一个类的所有对象共享相同的数据 我认为实例变量在类范围内使用,而静态变量只在它们自己的方法中有作用域 在类属性的上下文中,static具有不同的含义。如果您的字段类似于: private static int sharedAttribute; 然后,类的每个实例都将共享相同的变量,因此,如果在一个实例中更改它,则更改将反
静态变量表示类范围的信息。一个类的所有对象共享相同的数据
我认为实例变量在类范围内使用,而静态变量只在它们自己的方法中有作用域 在类属性的上下文中,
static
具有不同的含义。如果您的字段类似于:
private static int sharedAttribute;
然后,类的每个实例都将共享相同的变量,因此,如果在一个实例中更改它,则更改将反映在更改之前或之后创建的所有实例中
这样说来,您可能理解这在许多情况下是不好的,因为它很容易变成不希望的副作用:更改对象a
也会影响b
,并且您可能会想知道为什么b
更改时没有明显的原因。无论如何,在某些情况下,这种行为是绝对可取的:
常量
,所以让所有类访问相同的值不会有什么害处,因为没有人可以更改它们。如果您有很多该类的实例,它们也可以节省内存。不过,不确定并发访问static
vars是在程序启动之前实例化的,所以如果有太多vars,可能会降低启动速度
static
方法只能访问static
属性,但在尝试此方法之前请三思
经验法则:不要使用
静态
,除非这是必要的,并且您知道自己在做什么,或者您正在声明一个类常量 我认为您正在考虑静态关键字的C/C++定义。在这里,static关键字有很多用途。在Java中,静态关键字的功能在您的文章中进行了描述。无论如何,你可以自己试试:
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();
a.x = 1; // This will give an error, but still compile.
b.x = 2;
System.out.println(a.x); // 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();
a.x = 1;
b.x = 2;
System.out.println(a.x); // Should print 1.
}
}
假设有一个测试类:
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(实例变量)的单独副本
所以
希望这能解释您的查询。考虑一个类
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
,因为obj1
和obj2
都引用同一个变量。对于非静态变量,输出会有所不同,因为每个对象在创建时都保留其自身的非静态变量副本;对它们所做的更改不会影响由另一个对象创建的变量的另一个副本。假设我们创建一个静态变量K,并在主函数中创建三个对象:
ob1
ob2
ob3;
所有这些对象都可以具有相同的变量K值。相反,如果变量K是实例变量,则可能具有不同的值,如下所示:
ob1.k
ob2.k
ob3.k您可能会将静态和本地混淆。方法中声明的变量是局部变量,仅在调用该方法时存在。静态变量与实例变量类似,只是它们属于实际的
类对象,而不是类的特定实例,因此可以从类的所有实例访问相同的变量。谢谢,如果声明静态变量,只有当我有兴趣更改该类每个对象的所有值时,我才会这样做,例如,如果我为员工的工资率声明了一个静态变量,那么我可以通过执行类似employee.rate\u of\u pay?的操作来更新所有员工的工资率。很明显,这种改变只会影响它之后发生的操作。因此,如果您想在更改工资率后重新计算工资,则必须在更改后调用recreactewage()
或类似的函数。
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);
}
}