这与企业 Java 开发人员在将枚举持久保存到数据库时面临的问题相同。现有答案的问题在于它们很脆弱并且不适合重构。这就是为什么(底部有替代方案。)
使用枚举toString()
和valueOf()
方法意味着不能重命名枚举值。假设我有一个带有值和的VehicleType
枚举。如果我将字符串“TRUCK”存储为首选项值,然后在我的应用程序的下一个版本中重命名为,则存储的字符串不再有意义并且会抛出.CAR
TRUCK
VehicleType.TRUCK
VehicleType.PICKUP_TRUCK
valueOf()
IllegalArgumentException
使用值的序数意味着枚举值无法重新排序,或者您存储的值将不再匹配。这种情况可能会更糟,因为您的应用程序将继续运行,但可能会以意想不到的方式运行,一旦最终发现问题就很难追踪并且可能无法纠正。除了结尾之外的任何地方添加新值也是如此。如果我MOTORCYCLE
在顶部添加一个新值,CAR
在以前版本的应用程序中存储为它的序数 (0) 将MOTORCYCLE
在更新后返回,并且 a 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))
。
这种方法需要一些额外的代码,但在我看来,它是最强大的解决方案。