Java 静态和非静态变量在同一个 class

Java static and non-static variables in the same class

我需要一些帮助来澄清静态和非静态变量。据我了解,静态变量在 class 的所有实例中具有相同的值。但是,假设我在同一个 class 中混合了静态和非静态变量。当我引用静态变量时,无论使用哪个实例,我都会得到相同的值?然而,当我引用一个非静态变量时,我将获得与该特定 class 关联的值?这似乎是一场内存管理噩梦。这真的是它的工作原理吗?静态内存是如何处理的?是在每个实例中创建变量的多个副本然后以某种方式同步还是在每个实例中创建地址引用?在同一个 class 中混合使用静态和非静态变量是否存在任何缺陷? TIA.

你的断言是正确的......有点。 class 的实例之间并没有真正共享静态,因为您 不需要 一个 class 实例来引用一个。

public class Foo {
   public static String MYSTRING = "test";
}

无需 Foo 实例即可访问

String localString = Foo.MYSTRING;

我不太担心 JVM 如何选择存储静态变量的内存引用,这是委托给 JVM 设计人员的实现细节。

拥有同时定义静态和非静态(实例)变量的 class 没有任何缺陷,它一直都在发生并且非常自然...只要您了解如何静力学工作,你似乎做到了。

摘自OCA Java SE 7 Programmer I Certification Guide: Prepare for the 1ZO-803 exam:

STATIC VARIABLES

static variables belong to a class. They are common to all instances of a class and aren’t unique to any instance of a class. static attributes exist independently of any instances of a class and may be accessed even when no instances of the class have been created. You can compare a static variable with a shared variable. A static variable is shared by all of the objects of a class.

STATIC METHODS

Static methods aren’t associated with objects and can’t use any of the instance variables of a class. You can define static methods to access or manipulate static variables

You can also use static methods to define utility methods, which are methods that usually manipulate the method parameters to compute and return an appropriate value

The non-private static variables and methods are inherited by derived classes. The static members aren’t involved in runtime polymorphism. You can’t override the static members in a derived class, but you can redefine them. Any discussion of static methods and their behavior can be quite confusing if you aren’t aware of inheritance and derived classes.

Static 变量在整个程序中是相同的,因为它们没有被实例化。这确实是拥有静态变量的全部意义所在。它们不是 "somehow the same value",它们是相同的值,因为它们从未被实例化,并且在 运行 时间内只有一个来自相同 class 的同名静态变量。

我不知道后面的'memory logic',但是我创建了一个例子

public class TestClass {

private static int a = 1;
private int b = 1;

public static void main(String[] args) {
    TestClass firstInstance = new TestClass();
    TestClass secondInstance = new TestClass();

    // 'a' shouldn't be accessed like firstInstance.a, use TestClass.a instead(!)
    System.out.println("firstInstance  a: "+firstInstance.a+" b: "+firstInstance.b);  // firstInstance  a: 1 b: 1
    System.out.println("secondInstance a: "+secondInstance.a+" b: "+secondInstance.b);// secondInstance a: 1 b: 1

    firstInstance.a = 2; 
    firstInstance.b = 2;

    System.out.println("firstInstance  a: "+firstInstance.a+" b: "+firstInstance.b);  //firstInstance  a: 2 b: 2
    System.out.println("secondInstance a: "+secondInstance.a+" b: "+secondInstance.b);//secondInstance a: 2 b: 1 
    //a is now 2 also for 'secondInstance' because it's static, secondInstance.b didn't change because b exists specifically for each instance 

    /*
     * You can access 'a' even when no instance of TestClass exists
     * think about a simple Dog class where the amount of legs is 4 for every dog, so you can make it static, 
     * but not every Dog has the same name, so it wouldn't be clever to make the name static
     */
}
}