考虑一下下面的代码段。
public static UserStatus getEnum(int code) {
switch (code) {
case 0:
return PENDING;
case 1:
return ACTIVE;
case 2:
return SUSPENDED;
case 3:
return DELETED;
case 4:
return LOGIN_DISABLED;
default:
return null;
}
}现在,案例中的数字3和4(案例3和案例4)被声纳检测为魔术数字。
为了避免这个问题,我修改了我的代码段,如下所示...
public static UserStatus getEnum(int code) {
final int Pending=0;
final int Active=1;
final int Suspended=2;
final int Deleted= 3;
final int Login_details=4;
switch (code) {
case Pending:
return PENDING;
case Active:
return ACTIVE;
case Suspended:
return SUSPENDED;
case Deleted:
return DELETED;
case Login_details:
return LOGIN_DISABLED;
default:
return null;
}
}在这种情况下,这是解决幻数问题的好方法吗?
发布于 2013-03-21 12:27:48
您的解决方案并不是特别有效,因为它只是将文字移动到方法的顶部。它获得了一点好处,因为它为常量指定了有意义的名称,但这些名称是该方法的私有名称。
如果枚举的声明顺序与常量相同:
enum UserStatus {PENDING, ACTIVE, SUSPENDED, DELETED, LOGIN_DISABLED}你可以做另一个小把戏:
public static UserStatus getEnum(int code) {
UserStatus[] values = UserStatus.values();
return (code >= 0 && code < values.length) ? values[code] : null;
}但是,这在常量值和枚举声明之间创建了一个链接。这可能是可以的,这取决于调用getEnum时生成实际参数值的位置。
发布于 2013-03-21 14:25:28
问题是简单而明显的:当人们阅读你的代码时,为什么1会给出挂起并不明显。1的含义是什么?
你应该赋予它语义上的含义。使用常量是通常应该做的事情:
(假设getEnum()是UserService的一部分,代码应该如下所示)
public interface UserService {
public static final int USER_STATUS_VAL_PENDING = 1;
public static final int USER_STATUS_VAL_ACTIVE = 2;
UserStatus getUserStatus(int userStatusVal);
}
public class SimpleUserService implements UserService {
public UserStatus getUserStatus(int userStatusVal) {
switch userStatusVal {
case USER_STATUS_VAL_PENDING:
return UserStatus.PENDING;
case USER_STATUS_VAL_ACTIVE:
return UserStatus.ACTIVE;
//.....
}
}正如另一个答案所建议的,您可以依赖enum的序数值来执行int-enum映射。然而,您必须意识到,如果您重新排列枚举的值,或者在末尾之外的位置添加新的值,这种方法可能会导致问题。序数值将被更改,您无法覆盖它。
另一件需要注意的事情是,在你的代码中有一些你没有做好的事情:
的常量使用ALL_CAP_UNDERSCORE_DELIMITED
https://stackoverflow.com/questions/15539435
复制相似问题