首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >魔数问题的解决方案……?

魔数问题的解决方案……?
EN

Stack Overflow用户
提问于 2013-03-21 12:21:30
回答 2查看 13.5K关注 0票数 2

考虑一下下面的代码段。

代码语言:javascript
复制
 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)被声纳检测为魔术数字。

为了避免这个问题,我修改了我的代码段,如下所示...

代码语言:javascript
复制
 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;
    }
}

在这种情况下,这是解决幻数问题的好方法吗?

EN

回答 2

Stack Overflow用户

发布于 2013-03-21 12:27:48

您的解决方案并不是特别有效,因为它只是将文字移动到方法的顶部。它获得了一点好处,因为它为常量指定了有意义的名称,但这些名称是该方法的私有名称。

如果枚举的声明顺序与常量相同:

代码语言:javascript
复制
enum UserStatus {PENDING, ACTIVE, SUSPENDED, DELETED, LOGIN_DISABLED}

你可以做另一个小把戏:

代码语言:javascript
复制
public static UserStatus getEnum(int code) {
    UserStatus[] values = UserStatus.values();
    return (code >= 0 && code < values.length) ? values[code] : null;
}

但是,这在常量值和枚举声明之间创建了一个链接。这可能是可以的,这取决于调用getEnum时生成实际参数值的位置。

票数 7
EN

Stack Overflow用户

发布于 2013-03-21 14:25:28

问题是简单而明显的:当人们阅读你的代码时,为什么1会给出挂起并不明显。1的含义是什么?

你应该赋予它语义上的含义。使用常量是通常应该做的事情:

(假设getEnum()是UserService的一部分,代码应该如下所示)

代码语言:javascript
复制
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映射。然而,您必须意识到,如果您重新排列枚举的值,或者在末尾之外的位置添加新的值,这种方法可能会导致问题。序数值将被更改,您无法覆盖它。

另一件需要注意的事情是,在你的代码中有一些你没有做好的事情:

  1. 的目的是通过使整数文本成为常量来赋予其语义含义,它应该对调用者可见,因此局部最终变量不是正确的方法。
  2. 您应该对名为

的常量使用ALL_CAP_UNDERSCORE_DELIMITED

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15539435

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档