为何抽象类子类数组会出现重复数据?
问题分析与解决方案
兄弟,你这个问题我刚学面向对象的时候也踩过一模一样的坑!核心问题不是if/else的逻辑,而是你创建子类对象的位置错了——大概率你是在for循环外面只new了一个子类对象,然后每次循环里只是修改这个对象的属性,再把它塞进数组里。这样数组里的所有元素其实都是同一个对象的引用,最后自然全显示最后一次输入的数据。
错误写法示例(你可能是这样写的)
// 抽象类 abstract class Account {} // 子类 class SavingsAccount extends Account { private String name; // setter/getter省略 } public class Test { public static void main(String[] args) { Account[] accounts = new Account[5]; // 错误:在循环外创建对象,复用同一个实例 SavingsAccount sa = new SavingsAccount(); for (int i = 0; i < 5; i++) { // 假设这里是你的if/else逻辑,只是修改sa的属性 if (i % 2 == 0) { sa.setName("用户" + i); } else { sa.setName("测试用户" + i); } accounts[i] = sa; } // 打印时全是最后一次的"测试用户4" for (Account acc : accounts) { System.out.println(((SavingsAccount)acc).getName()); } } }
正确写法:在循环内创建新对象
你需要把对象的创建放到for循环内部(或者if/else的分支里,如果有多个子类的话),确保每次循环都生成一个全新的对象实例,这样数组里的每个元素都指向不同的内存地址,各自保存自己的属性值。
public class Test { public static void main(String[] args) { Account[] accounts = new Account[5]; for (int i = 0; i < 5; i++) { // 正确:每次循环都创建新的对象 SavingsAccount sa = new SavingsAccount(); if (i % 2 == 0) { sa.setName("用户" + i); } else { sa.setName("测试用户" + i); } accounts[i] = sa; } // 现在打印会显示各自的内容:用户0、测试用户1、用户2... for (Account acc : accounts) { System.out.println(((SavingsAccount)acc).getName()); } } }
为什么会出现这种情况?
因为Java里数组存储的是对象的引用(内存地址),而不是对象本身。如果一直复用同一个对象,数组里的所有元素都指向同一块内存空间,你每次修改属性都是在修改这块空间里的数据,最后自然全是最后一次修改的结果。而每次创建新对象,就会开辟新的内存空间,每个引用指向不同的空间,数据就不会被覆盖了。
如果你的if/else是用来判断创建不同子类的对象(比如有的时候创建SavingsAccount,有的时候创建CurrentAccount),那也要在对应的分支里new新对象,而不是复用同一个实例哦!
内容的提问来源于stack exchange,提问作者nSqui
相关产品推荐
相关产品推荐

