我遇到了一个关于将实例变量设为静态的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。有人能帮我理解吗?
感谢。
答案 0 :(得分:3)
我认为您在final
和static
变量之间感到困惑。
最终(但不是静态)变量与实例绑定,可以在构造函数中获取值,也可以通过静态初始化。
静态变量与类绑定,因此它们在给定类的所有实例的一个JVM实例之间共享相同的值。
最终的静态变量提供了两者中最受限制的变量:它是有效的常量:无法更改,并且对于给定类的所有实例都是相同的。
结论:
this.name = name;
语句更新一个绑定到类的值,而不是单个实例,所以在这样的调用之后,每个实例都会“看到”相同的值 - 最后一个赋值操作的结果。
答案 1 :(得分:2)
第二个断言不会失败,因为这一行:
Student studentB = new Student("b");
将更改所有实例的name
变量。
因此,当第二个断言出现时,Student.name
是 "b"
。 (请注意,这是我在这里引用的Student
类。)
第三个断言确实会失败,因为所有实例name
(studentA
和studentB
现在都是"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”)。