Integer.toString(int i)与String.valueOf(int i)


175

我想知道为什么该方法String.valueOf(int i)存在?我正在使用此方法转换intString并发现了该Integer.toString(int i)方法。

看完这些方法的实现后,我看到第一个正在调用第二个。结果,我所有的String.valueOf(int i)通话都比直接通话多了一个电话Integer.toString(int i)


Answers:


46

做同一件事的只是两种不同的方式。这可能是历史原因(不记得一个人在另一个人之前)。


22
是的,但是如果某事正在做同样的事情,并不意味着那是同一件事。
DamianLeszczyński-Vash

3
String.valueOf(int)只是直接调用Integer.toString(i)。因此最好调用Integer.toString(int)。
djchapm

171

在字符串类型中,我们有几种方法valueOf

static String   valueOf(boolean b) 
static String   valueOf(char c) 
static String   valueOf(char[] data) 
static String   valueOf(char[] data, int offset, int count) 
static String   valueOf(double d) 
static String   valueOf(float f) 
static String   valueOf(int i) 
static String   valueOf(long l) 
static String   valueOf(Object obj) 

如我们所见,这些方法能够解析所有类型的数字

像您介绍的那样,每种特定方法的实现:对于整数,我们有

Integer.toString(int i)

对于双

Double.toString(double d)

等等

在我看来,这不是历史性的事情,但是对于开发人员而言,使用valueOfString类中的方法比使用正确类型中的方法更有用,因为它使我们进行的更改更少。

范例1:

public String doStuff(int num) {

  // Do something with num...

  return String.valueOf(num);

 }

示例2:

public String doStuff(int num) {

 // Do something with num...

 return Integer.toString(num);

 }

正如我们在示例2中看到的,与示例1相反,我们必须做两个更改。

在我的结论中,使用valueOfString类中的方法更灵活,这就是为什么可以在其中使用它的原因。


18
而且不要忘记Integer.toString(int i, int radix),将转换到比10等碱基串
斯蒂芬·P

@Vash您能否也解释一下使用空字符串将int转换为String与String.valueOf比较?例如)“” + int i =“ i”?哪个最好?
Kanagavelu Sugumar

1
若要将int格式化为字符串,则不应使用“” + i。没有太大的开销,但是通常因为这并不优雅。除了使用之外String.valueOf(int),您还可以使用String.format("%d",i);来了解更多信息,请访问此网站docs.oracle.com/javase/6/docs/api/java/util/Formatter.html
-Vash

我希望自动装箱更聪明,并且只需在编译时添加转换即可。
Rob Grant

1
@RobertGrant这里不是自动装箱。但是要回答您的问题,这样做很聪明,int i = new Integer("1");反之亦然。
DamianLeszczyński-Vash

52

一个巨大的区别是,如果您调用toString()一个null对象,则将得到一个NullPointerException反之,而使用则String.valueOf()可能不会检查null。


46
问题是关于Integer.toString(int i)一种static方法。没有null可能的对象。
PetrJaneček2012年

14
Integer i = null; i.toString(); // Null pointer exception!! String.valueOf(i); // No exception
manish_s 2012年

10
@Manis Kumar:您的示例将不会触发该String.valueOf(int i)方法,但是String.valueOf(Object obj)。无论如何,问题是关于原始int值,在这里没有的可能性null
hleinone 2012年

1
@manish_s从示例中可以很清楚地看出,没有人在谈论对象类型Integer。我们只在谈论原语。
Daniel Ochoa

2
@manish_s:OP没有说,Integer.toString()而是Integer.toString(int i)。那是一个静态方法(docs.oracle.com/javase/7/docs/api/java/lang/…)。
LarsH 2016年

13

String类为所有原始类型和Object类型提供valueOf方法,因此我认为它们是可以通过一个类访问的便捷方法。

NB分析结果

平均intToString = 5368ms,平均stringValueOf = 5689ms(对于100,000,000次操作)

public class StringIntTest {


    public static long intToString () {
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            String j = Integer.toString(i);
        }
        long finishTime = System.currentTimeMillis();

        return finishTime - startTime;
    }

    public static long stringValueOf () {

        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            String j = String.valueOf(i);
        }
        long finishTime = System.currentTimeMillis();

        return finishTime - startTime;
    }

    public static void main(String[] args) {
        long intToStringElapsed = 0;
        long stringValueOfElapsed = 0;
        for (int i = 0; i < 10; i++) {
            intToStringElapsed += intToString();
            stringValueOfElapsed+= stringValueOf();
        }
        System.out.println("Average intToString = "+ (intToStringElapsed /10));
        System.out.println("Average stringValueOf = " +(stringValueOfElapsed / 10));
    }
}

7
您的配置文件实际上应该有一个“热身”期,否则JIT修改内容可能会扭曲结果。也就是说,在10 ^ 8次操作中300ms的差异很小,以至于可以完全忽略不计。
卡梅隆·斯金纳

1
@Kingo我认为您的测试用例不正确。因为您正在将值分配给String j但从未使用过。底层编译器可能对此进行了优化。最好以不同的方法传递j对象并执行一些虚拟操作。
Rakesh

1
您真的不应该以这种方式编写本地的微型基准测试。如果您使用JMH。它将进行预热,时间测量,多次独立尝试(分叉Java!)并使代码变小(包括不同方法和值的结果-运行时7分钟):gist.github.com/ecki/ 399136f4fd59c1d110c1 (扰流板:“” + n获胜)。
eckes 2015年

5
谢谢哥们,但是我的答案是5年前!JMH仅在2013年发布:P
Kingo,

9

从Java来源:

/**
 * Returns the string representation of the {@code int} argument.
 * <p>
 * The representation is exactly the one returned by the
 * {@code Integer.toString} method of one argument.
 *
 * @param   i   an {@code int}.
 * @return  a string representation of the {@code int} argument.
 * @see     java.lang.Integer#toString(int, int)
 */
public static String valueOf(int i) {
    return Integer.toString(i);
}

因此,它们给出的结果完全相同,而一个实际上称为另一个。如果以后可以更改类型,则String.valueOf更为灵活。


8

如果查看String该类的源代码,则实际上在调用Integer.toString()时会调用它valueOf()

话虽如此,Integer.toString()如果未在编译时优化方法调用(可能是这样),则可能会更快一些。


是的,“” + n甚至更快。见gist.github.com/ecki/399136f4fd59c1d110c1
eckes


2

要回答OP的问题,它只是一个辅助包装程序,可以进行其他调用,并最终取决于样式选择。我认为这里存在很多错误信息,Java开发人员可以做的最好的事情就是查看每种方法的实现,在任何IDE中只需单击一两次即可。您将清楚地看到,这String.valueOf(int)只是在呼唤Integer.toString(int)您。

因此,绝对差为零,因为它们都创建了一个char缓冲区,遍历数字中的数字,然后将其复制到新的String中并返回它(因此每个都创建一个String对象)。唯一的区别是一个额外的调用,编译器还是将其消除为单个调用。

因此,除了代码一致性以外,与您所谓的无关紧要。至于有关null的注释,它需要一个原语,因此不能为null!如果不初始化要传递的int,则会收到编译时错误。因此,由于在这种情况下不存在null,因此如何处理null也没有区别。


您能否将您的文本分成几个块。这很难读。
Magnilex

此操作中存在很多误会。您的帖子对我来说是最好的答案!谢谢
aksappy 2015年

1

您不必担心这种额外的通话会浪费您的效率问题。如果有任何成本,它将是最小的,并且从整体上看应该可以忽略不计。

两者之所以存在,可能是为了提高可读性。在将许多类型转换为的情况下,与的String各种调用相比,对的各种调用String.valueOf(SomeType)可能更具可读性SomeType.toString


1
实际上,这样的单线呼叫很快就会内联。
塔索斯·巴索科斯

即使在调用1000000时间的循环中String.valueof()?
曼努埃尔·塞尔瓦

@Manuel:你有个人资料吗?您是否确定这是性能问题所在?您确定没有过早优化吗?@Tassos:是的,这也是很有可能的,但是无论哪种方式,除非分析表明该特定调用存在问题,否则我都不会担心。
polygenelubricants

实际上,曼努埃尔(Manuel),我希望循环进行一次1000000次而不是一两次就可以更频繁地内联。即便如此,无论循环多少次,它仍然只是一小部分时间。
corsiKa 2010年

不,但是我确定我的应用程序中没有瓶颈。我之所以这样问是因为我在这里看不到任何可读性问题,因此我认为即使增益为0,我也必须使用更优化的代码。您不同意吗?
曼努埃尔·塞尔瓦

1

我的想法是valueof()总是被称为tostring()来表示,因此对于原始类型的表示法valueof被概括化了。默认情况下,java不支持数据类型,但是它使用objaect定义其工作并将其分类为cllas和made object .here Integer.toString(int i)创建仅对整数进行转换的限制。


1

Integer.toString(5)和String.valueOf(5)之间没有区别;

因为String.valueOf返回:

public static String valueOf(int i) {
    return Integer.toString(i);
}
public static String valueOf(float f) {
    return Float.toString(f);
}

等等..


0

使用String.valueOf()方法,您不必担心数据(它是否是int,long,char,char [],boolean,Object),您只需调用:

  • 静态字符串valueOf()

使用唯一语法String.valueOf()可以将您作为参数传递的任何内容转换为String并返回。

否则,如果使用Integer.toString(),Float.toString()等(即SomeType.toString()),则必须检查要转换为字符串的参数的数据类型。因此,最好使用String.valueOf()进行此类转换。

如果您有一个包含不同值(例如Integer,Char,Float等)的对象类数组,则可以使用String.valueOf()方法将此类数组的元素轻松转换为String形式。相反,如果要使用SomeType.toString(),则首先需要了解它们的数据类型类(可能使用“ instanceOf”运算符),然后才可以进行类型转换。

String.valueOf()方法在被调用时与传递的参数匹配(无论其Integer,Char,Float等),并通过使用方法重载来调用参数匹配的“ valueOf()”方法,然后在该方法内直接调用相应的“ toString()”方法。

因此,我们可以看到如何消除检查数据类型然后再调用相应的“ toString()”方法的开销。只需要调用String.valueOf()方法,而不必关心要转换为String的内容。

结论:String.valueOf()方法具有其重要性,只是需要再调用一次。


-3

toString()

  1. 存在于Object类中,通常在派生类中被覆盖
  2. 要调用toString()方法,必须将类型转换为适当的类。

的价值()

  1. String类中存在重载的静态方法。
  2. 处理基本类型以及对象类型。

    Integer a = null;
    System.out.println(Integer.toString()) ; NUll pointer exception
    System.out.println(String.valueOf() ; give NULL as value

检查此链接非常好。http://code4reference.com/2013/06/which-one-is-better-valueof-or-tostring/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.