如何限制Car类brightPainting与carKind属性的setter可选值?
当然可以实现这种属性值的限制!这正是Java封装特性的核心应用场景之一——通过在setter方法中添加参数校验,确保类的属性始终处于合法状态。下面我会给你两种实现方案,从基础的字符串校验到更健壮的枚举方案,一步步来:
基础实现:直接在Setter中做字符串校验
这种方式适合快速实现需求,直接在setter方法里判断输入是否符合要求,不符合就抛出异常提示调用方:
public class Car { private String model; private String color; private String brightPainting; // Yes or No private String carPlate; private String carKind; // little car, family car, sport car // Model的getter和setter public String getModel() { return model; } public void setModel(String model) { this.model = model; } // Color的getter和setter public String getColor() { return color; } public void setColor(String color) { this.color = color; } // BrightPainting的getter和带校验的setter public String getBrightPainting() { return brightPainting; } public void setBrightPainting(String brightPainting) { // 严格校验输入为"Yes"或"No",如果需要忽略大小写可以用equalsIgnoreCase if ("Yes".equals(brightPainting) || "No".equals(brightPainting)) { this.brightPainting = brightPainting; } else { // 抛出非法参数异常,明确告知调用方输入不合法 throw new IllegalArgumentException("brightPainting must be either 'Yes' or 'No'"); } } // CarPlate的getter和setter public String getCarPlate() { return carPlate; } public void setCarPlate(String carPlate) { this.carPlate = carPlate; } // CarKind的getter和带校验的setter public String getCarKind() { return carKind; } public void setCarKind(String carKind) { // 用switch判断是否为允许的选项,也可以用List.contains()实现 switch (carKind) { case "little car": case "family car": case "sport car": this.carKind = carKind; break; default: throw new IllegalArgumentException("carKind must be one of: 'little car', 'family car', 'sport car'"); } } }
关键逻辑说明:
- 对于
brightPainting:我们直接判断传入字符串是否是指定的两个值,不符合就抛出IllegalArgumentException,让调用方立刻知道输入错误。如果需要兼容大小写(比如允许"yes"或"NO"),把判断条件改成"Yes".equalsIgnoreCase(brightPainting)即可。 - 对于
carKind:除了switch,你也可以用集合包含判断,比如Arrays.asList("little car", "family car", "sport car").contains(carKind),两种方式都能实现校验。
更优方案:使用枚举类型(推荐)
如果想彻底避免字符串拼写错误(比如不小心把"little car"写成"litle car"),使用枚举类型是更健壮的选择。枚举可以把合法选项固化成类型,调用方只能传入预定义的枚举实例:
首先定义两个枚举类:
// 定义BrightPainting的合法状态 public enum BrightPaintingStatus { YES("Yes"), NO("No"); private final String displayValue; BrightPaintingStatus(String displayValue) { this.displayValue = displayValue; } // 获取字符串形式的值 public String getDisplayValue() { return displayValue; } // 可选:根据字符串值转换为枚举实例(方便从外部字符串输入转换) public static BrightPaintingStatus fromDisplayValue(String value) { for (BrightPaintingStatus status : values()) { if (status.displayValue.equals(value)) { return status; } } throw new IllegalArgumentException("Invalid bright painting status: " + value); } } // 定义CarKind的合法类型 public enum CarType { LITTLE_CAR("little car"), FAMILY_CAR("family car"), SPORT_CAR("sport car"); private final String displayValue; CarType(String displayValue) { this.displayValue = displayValue; } public String getDisplayValue() { return displayValue; } public static CarType fromDisplayValue(String value) { for (CarType type : values()) { if (type.displayValue.equals(value)) { return type; } } throw new IllegalArgumentException("Invalid car type: " + value); } }
然后修改Car类的属性和setter/getter:
public class Car { private String model; private String color; private BrightPaintingStatus brightPainting; private String carPlate; private CarType carKind; // 其他属性的getter/setter和之前一致,这里省略 public BrightPaintingStatus getBrightPainting() { return brightPainting; } // 直接接受枚举实例的setter public void setBrightPainting(BrightPaintingStatus brightPainting) { this.brightPainting = brightPainting; } // 可选:重载一个接受字符串的setter,方便外部传入字符串转换 public void setBrightPainting(String value) { this.brightPainting = BrightPaintingStatus.fromDisplayValue(value); } public CarType getCarKind() { return carKind; } public void setCarKind(CarType carKind) { this.carKind = carKind; } public void setCarKind(String value) { this.carKind = CarType.fromDisplayValue(value); } }
枚举方案的优势:
- 类型安全:调用方只能传入预定义的枚举值,完全杜绝了拼写错误的可能。
- 可读性更高:代码中直接用
BrightPaintingStatus.YES或CarType.SPORT_CAR,比字符串更清晰。 - 扩展性强:如果以后需要新增合法选项,直接修改枚举类即可,不用改动多处校验逻辑。
内容的提问来源于stack exchange,提问作者alexis rivas
相关产品推荐
相关产品推荐

