【问题标题】:Is it worth keeping constants for primitives in Java?是否值得在 Java 中为基元保留常量?
【发布时间】:2013-10-24 08:59:39
【问题描述】:

我的问题与Is making an empty string constant worth it?有关。

我知道常量应该有有意义的名称,但是在常量文件中提取原始值(如 Java 中的整数)有什么好处,例如:

public final static int ZERO = 0;

用作通用常量并在您的代码库中像Constants.ZERO一样继续重用它,还是更好地使用字面值0?

通用布尔值呢?即

public static final boolean TRUE = true;
public static final boolean FALSE = false;

【问题讨论】:

  • 对于这 3 个,不,没有任何好处。
  • 对于除booleans 以外的原始常量,最好使用常量变量以方便维护。在booleans 的情况下,没有任何好处。
  • @SotiriosDelimanolis 对于ints 等原始类型使用常量是有好处的。参考stackoverflow.com/q/47882/1065197
  • @Luiggi 我非常怀疑ZERO 会不会改变。
  • @LuiggiMendoza 一个常量如果给常量一个语义值是很有用的。 MAX_ITEMS 是一个有用的常量。 FIVE 不是(除非您希望在更改其值时拥有 FIVE = 10)。

标签: java primitive


【解决方案1】:

对于您定义的常量,没有理由使用它们,因为没有额外的含义。 0truefalse 文字已经有了它们的含义。

如果对这些值附加一些额外的含义,则值得创建常量,例如:

public static final int SUCCESS = 0;
public static final boolean DEBUG = true;

这些值背后是有意义的,它们可能会改变:

public static final int SUCCESS = 1;
public static final boolean DEBUG = false;

这将使更改值比更改程序中的大量文字更容易。

如果值具有超出其字面值的含义,并且可以更改,那么创建常量是值得的。

【讨论】:

  • 即使作为通用常量或全局变量,这些都没有价值?
  • 不,不是。 0 是 0。truetrue
【解决方案2】:

命名常量有两个很好的理由。最好的理由是通过命名常量(Pi、EarthDiameter、SpeedofLight、AvagadroNumber 等)来澄清代码,而不是直接引用值。另一种方法是命名被认为是恒定的数量,但可能会由于规格的变化而变化(例如:MAX_CHILD_THREADS、BtreeRadix)。但是将这些常量的定义放在一个位置,修改它们的值以满足未来的需要变得更加容易。

为您提到的常量(0,1,true,false 等)提供名称已经有其意义。将常数 0 命名为零实际上并没有增加任何内容。将空字符串命名为“”有一个小的价值,因为您提供了一些额外的含义 - 不仅仅是文字是“”,而是您的意思是说 EmptyString。

许多系统将数值定义为有意义,例如 Linux/Unix errno.h,为特定整数提供系统范围的含义。因此,诸如以下的定义是有价值的,

public static final int SUCCESS = 0;
public static final int EPERM = 1; // Operation not permitted
public static final int ENOENT= 2; // No such file or directory
public static final int ESRCH = 3; // No such process
public static final int EINTR = 4; // Interrupted system call

因为使用这些名称可以明确开发者的意图。

【讨论】:

    【解决方案3】:

    如果它使您的程序更易于理解或维护,是的。否则,不行。

    无论哪种方式,HotSpot VM 都可能将您的代码编译为相同的机器代码。

    顺便说一句,Boolean.TRUE 和 Boolean.FALSE 已经存在。

    【讨论】:

      【解决方案4】:

      给常量 0 指定一个特定于上下文的名称(如 NUM_EXCEPTIONS_TO_TOLERATE)比简单的零更有用,因为它不会传达太多信息。

      对于布尔值,变量名将传达上下文,因此将它们定义为常量没有多大意义。

      如果您担心空间问题,我认为premature optimization 太过分了。

      【讨论】:

      • 我更新了qn。因此,即使作为通用常量,即作为全局变量,它们也没有任何好处?
      【解决方案5】:

      布尔常量已经存在 Boolean.TRUEBoolean.FALSE

      我只使用这样的常量,如果它是一个幻数,在代码中硬编码它并不明显。

      private static final int SECS_PER_DAY = 86400;
      

      所以ZERO 本身并没有多大意义。

      【讨论】:

        【解决方案6】:

        我怀疑 ZERO、FALSE 或 TRUE 是否会改变它们的值。此外,FALSE 和 TRUE 在布尔类中定义(但不是原语)。

        【讨论】:

        • 是的,如果你想要真/假的字符串表示,你可以使用 Boolean.TRUE.toString() 或 Boolean.FALSE.toString()。
        【解决方案7】:

        使用类似的常量来避免“幻数”乱扔代码。也就是说,代码可读性为王,因此 SOME_SIGNIFICANT_NUMBER 比明显随机的 33、57、98 或其他任何值要好。

        如果您在多个地方引用它,维护可能会更容易 - 即,如果它们都使用相同的常量,您将不必更改 100 个文字。

        【讨论】:

          【解决方案8】:

          这一切都归结于代码的可读性。一个很好的衡量标准 - “WTF?!?!”的数量每分钟阅读您的代码的人。

          错误使用常量 - 记录不言自明的事情:

          // yeah, that we have bigger problems if that changes...
          public static final String WORLD_WIDE_WEB_PREFIX = "www";
          

          另一个例子 - 用一个常量替换一个直接的值同样有意义:

          // to be used in exactly 1 place
          private static final int RETRY_COUNT = 3;
          // ...
          // ... 480 lines later ...
          // ...
          public int getRetryCount() {
            // what's the value of this thing again?
            return RETRY_COUNT;
          }
          

          但是,对于前面的示例,如果您打算在多个位置使用 3 的值,则常量更好 - 它可以保证该数字的所有引用都是同步的(您将其从 3 更改为到 5,它们都变了)

          另一方面,

          // what's 143?!?! where do I go looking for what it means?!?!
          complexPart.setType(143);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2023-03-12
            • 2021-10-22
            • 1970-01-01
            • 1970-01-01
            • 2010-11-11
            • 2018-06-02
            • 1970-01-01
            相关资源
            最近更新 更多