【问题标题】:Static vs Instance Variables: Difference?静态变量与实例变量:区别?
【发布时间】:2014-02-07 21:16:52
【问题描述】:

静态变量和实例变量有什么区别。以下句子是我无法理解的:

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

我认为实例变量是在类范围内使用的,而静态变量只在它们自己的方法中具有作用域?

【问题讨论】:

  • 您混淆了 staticlocal。在方法中声明的变量是 local 并且仅在调用该方法时才存在。 静态变量类似于实例变量,只是它们属于实际的Class 对象而不是类的特定实例,因此可以从类的所有实例访问 SAME 变量。

标签: java class instance-variables static-variables


【解决方案1】:

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

private static int sharedAttribute;

那么,类的每一个实例都会共享同一个变量,所以如果你在一个实例中改变它,这个改变将反映在所有实例中,在更改之前或之后创建。

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

  1. 类常量:因为它们是const,所以让所有类访问相同的值不会有任何害处,因为没有人可以改变它。如果您有很多该类的实例,它们也可以节省内存。不过,不确定并发访问。
  2. 打算共享的变量,例如引用计数器 &co。

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

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

经验法则:不要使用static,除非有必要并且你知道你在做什么或者你正在声明一个类常量。

【讨论】:

  • 谢谢,所以如果声明一个静态变量,我只会在我对能够更改该类的每个对象的所有值感兴趣的情况下这样做,例如,如果我声明了一个静态变量对于员工的 rate_of_pay,我可以通过执行诸如employee.rate_of_pay 之类的操作来更新所有员工的工资率?
  • 没错。显然,该更改更改只会影响之后发生的操作。因此,如果您想在更改费率后重新计算工资,则必须在更改后致电 recalculateWage() 或类似电话。
【解决方案2】:

假设有一个测试类:

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,因为 a 由测试类的所有实例共享。 而实例变量每个都有单独的 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; 

希望能解释您的问题。

【讨论】:

    【解决方案3】:

    假设我们创建了一个静态变量 K 并且在 main 函数中我们创建了三个对象: ob1 ob2 OB3; 所有这些对象对于变量 K 可以具有相同的值。相反,如果变量 K 是实例变量,那么它可以具有不同的值,例如: ob1.k ob2.k ob3.k

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        考虑一个类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 都指的是同一个变量。对于非静态变量,输出不同,因为每个对象在创建时都保留自己的非静态变量副本;对它们所做的更改不会影响由另一个对象创建的变量的另一个副本。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-07-13
          • 2019-03-28
          • 1970-01-01
          • 2021-09-14
          • 1970-01-01
          • 1970-01-01
          • 2011-01-14
          • 2021-04-20
          相关资源
          最近更新 更多