静态变量导致Student数组所有元素输出最后一个值的问题排查
问题解答:所有Student对象打印结果均为最后一个对象的属性
你创建了10个Student对象存入数组,但打印时所有对象都显示最后一个对象(Ryan,74)的信息,调试发现每次创建新对象都会覆盖之前对象的属性值。
问题根源
你的怀疑完全正确——Student类的属性使用static修饰符是导致问题的核心原因。
在Java中,static修饰的属性属于类本身,而非类的实例对象。也就是说,无论你创建多少个Student对象,PIB和averageMark这两个属性只有一份副本,所有对象共享这同一个值。每次调用构造方法new Student(name, mark)时,都会直接覆盖类层面的PIB和averageMark值,最终所有对象的toString方法都会读取这份被最后一次赋值覆盖的类属性,自然全是最后一个对象的信息。
修正方案
去掉Student类属性的static修饰符,将其改为实例属性,让每个Student对象拥有自己独立的属性副本:
修正后的Student类
public class Student { // 改为实例属性,去掉static,同时建议改为private封装 private String PIB; private int averageMark; // 构造方法赋值给当前实例的属性 public Student(String name, int mark){ this.PIB = name; this.averageMark = mark; } @Override public String toString() { return "Name: " + PIB + ", Mark: " + averageMark; } }
Tester类无需修改
Tester类的逻辑是正确的,保持原代码即可:
public class Tester { public static Student[] SEstudents = new Student[10]; public static void main(String[] args) { setStudents(); printStudents(); } public static Student[] setStudents(){ SEstudents[0] = new Student("John", 95); SEstudents[1] = new Student("Micheal", 94); SEstudents[2] = new Student("Eve", 92); SEstudents[3] = new Student("Jack", 94); SEstudents[4] = new Student("Ann", 96); SEstudents[5] = new Student("Gabriel", 86); SEstudents[6] = new Student("John", 88); SEstudents[7] = new Student("Sophie", 96); SEstudents[8] = new Student("Tim", 73); SEstudents[9] = new Student("Ryan", 74); return SEstudents; } public static void printStudents(){ for(Student s: SEstudents){ System.out.println(s); } } }
补充说明
- 实例属性由每个对象独立拥有,赋值和读取都仅针对当前对象的副本,不会互相干扰。
- 构造方法中使用
this.明确指向当前实例的属性,可避免变量名歧义(也可以省略this.,但加上会更清晰)。 - 修改后toString方法读取的是当前实例的属性,就能正确输出每个对象独有的信息。
内容的提问来源于stack exchange,提问作者Tim Matthew
相关产品推荐
相关产品推荐

