使实例变量静态

时间:2012-11-28 13:07:52

标签: java

我遇到了一个关于将实例变量设为静态的Java问题:

public class Student {
 private static String name;

 public Student(String name) {
    this.name = name;
 }

 public String getName() {
  return name;
 }  
}

并测试:

public void testBadStatic() {
  Student studentA = new Student("a");
  assertEquals("a", studentA.getName());
  Student studentB = new Student("b");
  assertEquals("b", studentB.getName());
  assertEquals("a", studentA.getName());

我认为第二个assertEquals会失败,因为name变量是静态的,所以它已被赋值为“a”。但是,对于第二个断言,正确的输出应该为true,对于最后一个断言,应该为false。有人能帮我理解吗?

感谢。

6 个答案:

答案 0 :(得分:3)

我认为您在finalstatic变量之间感到困惑。

最终(但不是静态)变量与实例绑定,可以在构造函数中获取值,也可以通过静态初始化。

静态变量与类绑定,因此它们在给定类的所有实例的一个JVM实例之间共享相同的值。

最终的静态变量提供了两者中最受限制的变量:它是有效的常量:无法更改,并且对于给定类的所有实例都是相同的。

结论:

this.name = name;

语句更新一个绑定到类的值,而不是单个实例,所以在这样的调用之后,每个实例都会“看到”相同的值 - 最后一个赋值操作的结果。

答案 1 :(得分:2)

第二个断言不会失败,因为这一行:

Student studentB = new Student("b");

将更改所有实例的name变量。

因此,当第二个断言出现时,Student.name "b"。 (请注意,这是我在这里引用的Student类。)

第三个断言确实会失败,因为所有实例namestudentAstudentB现在都是"b"

换句话说:

Student studentA = new Student("a");
  // studentA.name = "a"
assertEquals("a", studentA.getName());    // This passes
Student studentB = new Student("b");
  // studentB.name = "b"
  // studentA.name = "b"
assertEquals("b", studentB.getName());    // This passes
assertEquals("a", studentA.getName());    // This fails

答案 2 :(得分:2)

  

public Student(String name){

这是你的构造函数。每当您创建此类的实例时,都会调用此“方法”。但是,静态变量属于该类。因此,将静态String名称设置为值会更改所有现有实例。

答案 3 :(得分:0)

尝试:

public class Student {
    private static String name;

    public Student(String name) {
        Studen.name = name;
    }

    public String getName() {
        return Student.name;
    }  
}

答案 4 :(得分:0)

静态变量在“不变”的意义上不是“静态” - 这意味着所有实例共享相同的变量,因此第二个构造函数调用用“b”替换静态变量的值。

答案 5 :(得分:0)

第二个断言将传递给构造函数中的静态变量赋值“b”。这也是第三个断言失败的原因(预期为“a”,发现为“b”)。