
通过将对象初始化时设定的属性(如骰子面数)直接用于实例方法中,可避免每次调用时重复传参,提升代码简洁性与封装性。
通过将对象初始化时设定的属性(如骰子面数)直接用于实例方法中,可避免每次调用时重复传参,提升代码简洁性与封装性。
在面向对象编程中,一个核心原则是“数据与行为绑定”——对象应自主管理其状态,并基于该状态提供行为。你当前的 Dice 类已将面数 sides 作为实例字段保存,但 rollDie(int sides) 方法却要求外部再次传入相同参数,这不仅冗余,还破坏了封装:一旦 sides 值被意外修改(例如在 rollDie(int sides) 中执行 this.sides = sides;),对象状态就可能失控。
✅ 正确做法是:移除参数依赖,直接使用 this.sides。只需新增一个无参重载方法 rollDie(),内部调用原有逻辑并传入 this.sides:
// Dice.java(优化后)
import java.util.Random;
public class Dice {
private final int sides; // 推荐使用 final,确保不可变性
public Dice(int sides) {
if (sides < 1) {
throw new IllegalArgumentException("Dice must have at least 1 side.");
}
this.sides = sides;
}
// 核心方法:使用对象自身状态,不依赖外部输入
public int rollDie() {
Random random = new Random();
return random.nextInt(sides) + 1; // nextInt(n) 生成 [0, n) 的整数,+1 得到 [1, n]
}
// (可选)保留带参方法仅用于特殊场景(如临时模拟不同面数),但不应修改 this.sides
public int rollDie(int tempSides) {
if (tempSides < 1) {
throw new IllegalArgumentException("Temporary sides must be positive.");
}
Random random = new Random();
return random.nextInt(tempSides) + 1;
}
}同时更新主程序,享受简洁调用:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
// Main.java
public class Main {
public static void main(String[] args) {
Dice d6 = new Dice(6);
System.out.println(d6.sides); // 输出: 6
System.out.println(d6.rollDie()); // 输出: 1–6 之间的随机整数(无需再传 6!)
System.out.println(d6.rollDie()); // 再次调用,结果独立且符合预期
}
}⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 避免副作用:原代码中 rollDie(int sides) 修改了 this.sides,这会导致对象状态意外变更。优化后的方法不再修改字段,保障了对象一致性;
- 使用 final 修饰 sides:一旦骰子创建完成,面数不应改变,final 能从编译期防止误修改;
- 边界校验:增加参数合法性检查(如 sides < 1),提升健壮性;
- 随机数生成优化:Random 实例建议复用(如声明为 private static final Random RANDOM = new Random();),避免频繁创建开销(本例为简洁性暂未展开,实际项目中推荐)。
总结:让方法“知道自己的事”,是良好封装的体现。当对象已持有必要状态时,方法应优先使用 this.xxx,而非要求调用者重复提供——这既是代码可读性的提升,更是面向对象设计思想的落地实践。

















