这与企业 Java 开发人员在将枚举持久保存到数据库时所面临的问题相同。现有答案的问题在于它们很脆弱并且不适合重构。这就是原因(底部有替代方案。)
使用枚举的toString() 和valueOf() 方法意味着无法重命名枚举值。假设我有一个 VehicleType 枚举,其值为 CAR 和 TRUCK。如果我将字符串“TRUCK”存储为首选项值,然后在我的应用程序的下一个版本中将VehicleType.TRUCK 重命名为VehicleType.PICKUP_TRUCK,则存储的字符串不再有意义,valueOf() 将抛出一个IllegalArgumentException。
使用值的序数意味着枚举值无法重新排序,或者您存储的值将不再匹配。这种情况可能会更糟,因为您的应用程序将继续运行,但可能会以意想不到的方式运行,一旦最终发现问题就很难追踪并且可能无法纠正。除了结尾之外的任何地方添加新值也是如此。如果我在顶部添加一个新的 MOTORCYCLE 值,则在之前版本的应用程序中存储为序号 (0) 的 CAR 在更新后将返回为 MOTORCYCLE,而 TRUCK (序号 1)会变成CAR。
我使用的替代方法是将final 字段添加到枚举并使用其值,如下所示:
public enum VehicleType {
CAR("C"),
TRUCK("T");
private final String code;
private static final Map<String,VehicleType> valuesByCode;
static {
valuesByCode = new HashMap<>(values().length);
for(VehicleType value : values()) {
valuesByCode.put(value.code, value);
}
}
VehicleType(String code) {
this.code = code;
}
public static VehicleType lookupByCode(String code) {
return valuesByCode.get(code);
}
public String getCode() {
return code;
}
}
使用类似preferences.putString("vehicle_type", vehicleType.getCode()) 的方式存储一个值并使用类似vehicleType = VehicleType.lookupByCode(preferences.getString("vehicle_type", null)) 的方式检索它。
这种方法需要一些额外的代码,但在我看来,它是最强大的解决方案。