
在java中创建多个hand实例时,若所有实例共用同一个list对象,会导致向任一实例添加卡片时其他实例也同步更新,根本原因是对象引用被重复传递而非独立初始化。
问题根源在于:原始Hand2类的构造方法接收一个外部List
此外,原代码还存在两个关键设计缺陷:
- cards字段未被使用却声明为实例变量;
- handValue为可变状态字段,且未在getHandValue()中重置,导致多次调用时结果累加(例如第二次调用会基于前一次的handValue继续累加),违反纯计算逻辑。
✅ 正确做法是让每个Hand2实例持有独立、私有的牌列表,并通过无参构造器内部初始化,彻底隔离状态:
public class Hand2 {
private final List hand = new ArrayList<>(); // 每个实例独有,不可变引用
public Hand2() {
// 无需外部传入List,内部自主初始化
}
public Cards addCard(Deck deck) {
Cards drawn = deck.dealCard();
hand.add(drawn);
return drawn;
}
public int getHandValue() {
int total = 0; // 局部变量,每次调用均重新计算
for (Cards card : hand) {
total += card.getValue();
}
return total;
}
@Override
public String toString() {
return "Hand: " + hand;
}
} 对应测试代码也需同步调整,移除共享List
立即学习“Java免费学习笔记(深入)”;
public static void main(String[] args) {
Deck deck = new Deck();
deck.shuffle();
Hand2 hand1 = new Hand2(); // 独立实例,独立列表
Hand2 hand2 = new Hand2(); // 另一个独立实例
hand1.addCard(deck);
hand2.addCard(deck);
hand2.addCard(deck);
System.out.println(hand1); // Hand: [Three of Diamonds]
System.out.println(hand2); // Hand: [Four of Clubs, Jack of Hearts]
System.out.println("hand1 value: " + hand1.getHandValue()); // 3
System.out.println("hand2 value: " + hand2.getHandValue()); // 14
}? 关键总结:
- ✅ 始终优先在类内部初始化集合类成员(如new ArrayList()),避免通过构造器暴露可变引用;
- ✅ 计算型方法(如getHandValue())应使用局部变量,禁止依赖并修改实例状态字段;
- ✅ 若需支持外部传入初始牌组,应使用防御性拷贝:this.hand = new ArrayList(externalList);
- ✅ 为增强健壮性,可将hand声明为final(如上所示),确保引用不可重绑定。
遵循以上原则,即可确保多玩家场景下各玩家手牌完全独立、状态互不干扰。










