软件SDK版本与服务器端API版本不一致的情况十分常见。优秀的SDK能够优雅地处理这种版本差异,兼容潜在的API变更。
对于在Android应用中使用的Java SDK而言,版本兼容性尤为重要,因为用户更新应用的速度往往较慢。应用不应该因为使用了旧版本的SDK而崩溃。
Java枚举的动态兼容性并非理想。以下是一个宠物店API的示例:
假设我们设计了一个代表订单状态的Java枚举:
立即学习“Java免费学习笔记(深入)”;
enum PetOrderStatus { PLACED, APPROVED, DELIVERED, }
用户发现枚举比字符串更方便,因为它能明确指示所有可能的状态,并可以使用switch表达式处理:
String displayText = switch (petOrderStatus) { case PLACED -> "Your order was placed and is being reviewed."; case APPROVED -> "Your order was approved."; case DELIVERED -> "Your order was delivered!"; };
但是,如何将API响应中的字符串转换为枚举常量呢?最常见的方法是使用valueOf()方法:
PetOrderStatus petOrderStatus = PetOrderStatus.valueOf(statusString.toUpperCase());
这种方法存在潜在问题:API变更。
假设产品经理要求添加“运输中”状态。我们更新SDK:
enum PetOrderStatus { PLACED, APPROVED, IN_TRANSIT, DELIVERED, }
String displayText = switch (petOrderStatus) { case PLACED -> "Your order was placed and is being reviewed."; case APPROVED -> "Your order was approved."; case IN_TRANSIT -> "Your order is on the way!"; case DELIVERED -> "Your order was delivered!"; };
部署后,我们收到崩溃报告:
Exception in thread "main" java.lang.IllegalArgumentException: No enum constant PetOrderStatus.IN_TRANSIT at java.lang.Enum.valueOf(Enum.java) at PetOrderStatus.valueOf(PetOrderStatus.java)
这是因为旧版SDK无法识别IN_TRANSIT。valueOf()方法在遇到未知值时会抛出异常。
解决方案
如何避免这种情况呢?一个方案是使用Optional
更强大的方案是存储原始API值,并同时访问原始值和枚举表示:
public final class PetOrderStatus { private final String value; private PetOrderStatus(String value) { this.value = value; } public static PetOrderStatus of(String value) { return new PetOrderStatus(value); } public String _value() { return value; } public Value value() { return switch (value) { case "PLACED" -> Value.PLACED; case "APPROVED" -> Value.APPROVED; case "DELIVERED" -> Value.DELIVERED; default -> Value._UNKNOWN; }; } public enum Value { PLACED, APPROVED, DELIVERED, _UNKNOWN, } }
用户可以这样使用:
String displayText = switch (petOrderStatus.value()) { case PLACED -> "Your order was placed and is being reviewed."; case APPROVED -> "Your order was approved."; case DELIVERED -> "Your order was delivered!"; case _UNKNOWN -> "Your order status is: " + petOrderStatus._value(); };
这种设计的好处:
API变更:第二部分
使用新的SDK设计,应用在API变更后不会崩溃。旧版应用会显示“Your order status is: IN_TRANSIT”。如果我们更新SDK和应用,添加IN_TRANSIT到枚举中,用户下次更新后就能看到正确的文本。
以上就是使Java枚举兼容的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号