在Java中,parseInt()和valueOf()之间有什么区别?

521

parseInt()valueOf()有什么不同?

在我看来,它们似乎做的事情完全一样(对于parseFloat()parseDouble()parseLong()等也是如此),那么它们与Long.valueOf(string)有何不同呢?

另外,按照惯例,这些方法中哪一个更可取且更常用?

11个回答

480

根据Integer.valueOf(String)的API文档,该方法确实会将String解释为与Integer.parseInt(String)相同。然而,valueOf(String)返回一个新的Integer()对象,而parseInt(String)则返回一个基本类型的int

如果你想享受到Integer.valueOf(int)所提供的潜在缓存优势,你可以使用这个丑陋的代码:

Integer k = Integer.valueOf(Integer.parseInt("123"))

如果你需要的是对象而不是原始类型,那么使用valueOf(String)可能比使用parseInt(String)创建新对象更为可取,因为前者在IntegerLongDouble等类中保持一致。


9
这两种方法在性能或内存方面有区别吗? - Logan
101
除了浪费计算机处理时间和增加程序大小之外,Integer.valueOf(Integer.parseInt("123"))Integer.valueOf("123")Integer.valueOf(123) 没有任何区别。 - Thomas Eding
12
valueOf方法可能会新分配一个对象(potentially),这个新对象需要占用更多的内存空间,并需要额外处理和垃圾回收,而普通的整数则非常“轻量级”。对于最常见的值,你会得到对预先存在的对象的引用,这可以稍微提高性能。 - foo
19
Integer.valueOf(String)Integer.valueOf(int) 做的缓存是完全一样的。实际上,它的实现方式是 Integer.valueOf(Integer.parseInt(…)) - Holger
11
它不可能返回一个原始的 int。方法签名表明它返回一个 Integer,并且确实如此。这个答案部分错误,因为它说它返回一个“新”的 Integer。这不是 Javadoc 中所说的。它可以返回一个缓存的 Integer - user207421
显示剩余5条评论

88

来自这个论坛:

parseInt()返回原始整数类型(int),而valueOf返回java.lang.Integer,这是代表整数的对象。有些情况下,您可能需要一个Integer对象,而不是原始类型。

当然,另一个明显的区别是intValue是一个实例方法,而parseInt是一个静态方法。


13
值得一提的是,valueOf版本还将使用内部引用池来返回给定值的相同对象,而不仅仅是具有相同内部值的另一个实例。这意味着通过这种方式返回的两个Longs,a.equals(b)== true并且a == b也为真。 - basszero
1
@bassezero。此外,该池有一个限制。我认为它是-127到127。 - OscarRyz
1
参考池的大小是实现细节的真正例子;它甚至可以在补丁发布中增加大小,您不应该对其进行任何依赖 - Donal Fellows
@OscarRyz 实际上是-128到127。请注意,JVM提供了一个参数来将缓存的最高边界设置得更高。但是,您无法重新定义最低边界:https://dev59.com/bV0b5IYBdhLWcg3wEdsx - Jean-François Savard
没有人提到intValue,为什么你的答案提到了intValue - Simon Forsberg
显示剩余2条评论

46
Integer.valueOf(s)

类似于

new Integer(Integer.parseInt(s))
差异在于 valueOf() 返回一个 Integer,而 parseInt() 返回一个 int(一种原始类型)。另外请注意,valueOf() 可能会返回已缓存的 Integer 实例,这可能会导致测试结果似乎间歇性地正确。在 自动装箱 之前,这可能会有便利上的差异,但在 Java 1.5 之后,这并不重要。

此外,Integer.parseInt(s) 还可以接受原始数据类型。


6
valueOf()方法在使用相同参数的连续调用中可能会返回相同的对象(对于-128到127之间的参数是必须这样做的)。而new Integer()总是会创建一个新对象。 - Adam Rosenfield
哪一个被更频繁地使用?我应该最常使用哪一个? - Ali
3
如果您需要一个整数,使用parseInt()函数;如果您需要一个Integer对象,使用valueOf()函数。 - matt b
@Joan d Silva 从你的最后一行来看,我认为 Integer.parseInt(s) 只能接受字符串作为输入参数,而 Integer.ValueOf(s) 则可以接受整数和字符串作为输入参数。 - Pratik

25

看一下 Java 的源代码:valueOf 使用了 parseInt

/**
 * Parses the specified string as a signed decimal integer value.
 *
 * @param string
 *            the string representation of an integer value.
 * @return an {@code Integer} instance containing the integer value
 *         represented by {@code string}.
 * @throws NumberFormatException
 *             if {@code string} cannot be parsed as an integer value.
 * @see #parseInt(String)
 */
public static Integer valueOf(String string) throws NumberFormatException {
    return valueOf(parseInt(string));
}

parseInt 返回的是 int 类型(而不是 Integer

/**
 * Parses the specified string as a signed decimal integer value. The ASCII
 * character \u002d ('-') is recognized as the minus sign.
 *
 * @param string
 *            the string representation of an integer value.
 * @return the primitive integer value represented by {@code string}.
 * @throws NumberFormatException
 *             if {@code string} cannot be parsed as an integer value.
 */
public static int parseInt(String string) throws NumberFormatException {
    return parseInt(string, 10);
}

6

Integer.parseInt可以直接返回int原生类型。

除非该整数恰好是预分配的整数之一,否则Integer.valueOf可能需要分配一个Integer对象。这会增加成本。

如果您只需要原生类型,请使用parseInt。如果您需要一个对象,请使用valueOf。

此外,由于可能存在分配问题,自动装箱并不总是好事。它可能会减慢速度。


5
  • valueOf - 将值转换为包装类
  • parseInt - 将值转换为基本类型

Integer.parseInt 仅接受字符串并返回基本整型(int)。

   public static int parseInt(String s) throws NumberFormatException {
        return parseInt(s,10);
    }

Iteger.valueOf可以接受int和String类型的参数。如果参数是String类型,valueOf会使用parseInt将其转换为简单的int类型,并且如果输入小于-128或大于127,则返回一个新的Integer对象。如果输入在范围(-128 - 127)内,它总是从内部的IntegerCache中返回Integer对象。Integer类维护一个内部静态IntegerCache类,作为缓存并保存从-128到127的整数对象,这就是为什么当我们尝试获取127(例如)的整数对象时,总是得到相同的对象。

Iteger.valueOf(200)将返回一个值为200的新Integer对象,就像new Integer(200)一样。 Iteger.valueOf(127)Integer = 127相同;

如果您想将String类型转换为Integer类型,请使用Iteger.valueOf

如果您想将String类型转换为简单的int类型,请使用Integer.parseInt。它的速度更快。

  public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

  public static Integer valueOf(String s) throws NumberFormatException {
        return Integer.valueOf(parseInt(s, 10));
  }

  private static class IntegerCache {
      static final int low = -128;
      static final int high;
      static final Integer cache[];

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
  }

比较 Integer.valueOf(127) == Integer.valueOf(127) 返回 true

Integer a = 127; // Compiler converts this line to Integer a = Integer.valueOf(127);
Integer b = 127; // Compiler converts this line to Integer b = Integer.valueOf(127);
a == b; // return true 

因为它使用来自缓存的具有相同引用的整数对象。

但是Integer.valueOf(128) == Integer.valueOf(128)是错误的,因为128超出了IntegerCache的范围,所以它返回一个新的Integer对象,因此这些对象将具有不同的引用。


请不要滥用加粗格式:它会降低您的帖子可读性。 - Zoe stands with Ukraine

1

parse*变量返回原始类型,而valueOf版本返回对象。我相信valueOf版本也会使用内部引用池来返回给定值的相同对象,而不仅仅是具有相同内部值的另一个实例。


其实并不完全正确。一开始我也是这么想的,但是 Integer.valueOf(String) 的 Javadocs 明确说明它等同于 new Integer(Integer.parseInt(String))。不过 Integer.valueOf(int) 确实会进行缓存。 - Michael Myers
对于字符串版本,你是正确的,我想的是原始版本。Long.valueOf(5)将始终返回相同的对象。 - basszero

0

public static Integer valueOf(String s)

  1. 该参数被解释为表示有符号十进制整数,就像将该参数传递给parseInt(java.lang.String)方法一样。
  2. 结果是一个Integer对象,它表示由字符串指定的整数值。

  3. 换句话说,该方法返回一个等于以下值的Integer对象: new Integer(Integer.parseInt(s))


0

0

可能是因为您正在使用jdk1.5+,它会自动转换为int。因此,在您的代码中,它首先返回Integer,然后自动转换为int。

您的代码与以下代码相同

int abc = new Integer(123);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接