Java整型常量声明-原语或对象



在Java中,用对象方式声明int常量有什么好处:

public final static Integer SOME_CONSTANT = Integer.valueOf(99);

代替经典

public final static int SOME_CONSTANT = 99;

我知道对象和原语之间的基本区别,也知道自动装箱。但是我在我们公司的代码中看到了这个声明,我想知道,将整型常量声明为对象有什么特别的原因吗?

这取决于您计划如何使用该常量。如果你有一个需要Integer的API,那么使用int表单将有一个小的性能损失,因为自动装箱。

如果你只需要原语,Integer的拆箱不是很昂贵,但很容易避免。

还要注意

Integer SOME_CONSTANT = Integer.valueOf(99);

完全相同
Integer SOME_CONSTANT = 99;

*.valueOf()方法被添加到API中,为编译器提供了一种自动框原语的通用方法。

这两者实际上有一些区别。查看字节码将揭示该信息。

public final static int SOME_CONSTANT = 99;

将是一个编译时间常数。所以这个东西的值将作为字节码本身的一部分。

字节码:

 public static final int SOME_CONSTANT;
   descriptor: I
   flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
   ConstantValue: int 99

public final static Integer SOME_CONSTANT1 = Integer.valueOf(99);

虽然Integer类的实例是不可变的,但它们不会变成编译时间常量。它们作为类的静态初始化器的一部分运行。

字节码:

 public static final java.lang.Integer SOME_CONSTANT1;
    descriptor: Ljava/lang/Integer;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
  static {};
    descriptor: ()V
    flags: ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: bipush        99
         2: invokestatic  #14                 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
         5: putstatic     #20                 // Field SOME_CONSTANT1:Ljava/lang
/Integer;
         8: return
      LineNumberTable:
        line 4: 0
        line 5: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature

通常使用第二种声明常量的方式,即使用原语int,而不是盒装的Integer

该规则的一个例外是,当您将常量放在集合中,并且常量在对象自动存储的数字范围之外时。您的代码可能会在这里或那里节省一些CPU周期,因此考虑将常量设置为Integer而不是int是公平的。这可以让你在将这些常量放入集合时节省自动装箱的成本。

一般来说,这是一种微优化:除非您将原语常量放在紧循环中的集合中,这将花费大量时间,否则使用这两个声明的代码之间不会有性能差异。

Integer常量可以为null,因此您不需要为无效或尚未设置的字段设置特殊值。但是根据常数,这个事实不是一个好的论据。

Integer常量的好处是它们具有用于解析的方法,以及更多的方法,并且可以使用Integer常量池。更多信息请看这篇文章:Java Integer: Constant Pool

来自Integer类中valueOf -方法的JavaDoc:

/**
 * Returns an {@code Integer} instance representing the specified
 * {@code int} value.  If a new {@code Integer} instance is not
 * required, this method should generally be used in preference to
 * the constructor {@link #Integer(int)}, as this method is likely
 * to yield significantly better space and time performance by
 * caching frequently requested values.
 *
 * This method will always cache values in the range -128 to 127,
 * inclusive, and may cache other values outside of this range.
 *
 * @param  i an {@code int} value.
 * @return an {@code Integer} instance representing {@code i}.
 * @since  1.5
 */

所以,当整型的值为[- 128,127]时,这似乎是一种增益,但在我看来,由于当今计算机的高性能,这在大多数情况下是可以忽略不计的。如果您有一个非常非常性能关键的应用程序,您可以从使用它中获得好处,否则我只会选择提供最佳可读性的(在我看来是自动装箱)。

如果自动装箱使用valueOf -方法,就像在另一个答案中所说的那样,那么当然没有区别,上面的比较将是Integer.valueOfnew Integer

Java是一种面向对象的语言…有许多任务可以在对象上执行,但不能在基本数据类型上执行…

例如集合只能存储对象…

你应该看看你公司的下一个代码也许他们会在某个地方使用这个常量作为对象或者可能是为了将来的使用他们会声明它为对象。

与Integer对象不同,int类型是基本类型,因此不能对其调用任何方法。

如果您想使用SOME_CONSTANT来执行某些操作,那么我认为将其声明为int会更好。

Integer类提供了一些有用的方法。有关更多信息,请参阅API: Integer Reference

最新更新