0

我遇到了一个关于使实例变量静态的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。有人可以帮我理解这一点吗?

谢谢。

4

6 回答 6

3

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

最终(但不是静态)变量与实例相关联,并且可以在构造函数中或通过静态初始化获取值。

静态变量与类相关联,因此对于给定类的所有实例,它们在一个 JVM 实例中共享相同的值。

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

结论:

this.name = name;

语句更新一个与类相关的值,而不是单个实例,因此在这样的调用之后,每个实例将“看到”相同的值 - 最后一次赋值操作的结果。

于 2012-11-28T13:11:58.763 回答
2

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

Student studentB = new Student("b");

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

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

第三个断言确实会失败,因为name对于所有实例(现在studentAstudentB现在都是"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
于 2012-11-28T13:11:03.447 回答
2

公共学生(字符串名称){

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

于 2012-11-28T13:11:35.687 回答
0

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

于 2012-11-28T13:11:30.730 回答
0

尝试 :

public class Student {
    private static String name;

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

    public String getName() {
        return Student.name;
    }  
}
于 2012-11-28T13:09:22.410 回答
0

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

于 2012-11-28T13:14:02.150 回答