Java学习笔记

这个太简单了,我也不会

2018-03-19  本文已影响17人  chenmingang

假设 userId 是 int 型,想 要一个 String 类型的 userId,String.valueOf(userId) 更好还是 userId + "" 更好。

最近有同学问了这样一个问题,咋一看似乎只是一个打码风格问题,但是如果非让你选一个好的怎么办呢,还是得测试一下呀。
简单的模拟一下场景:

//写法一:
public class Test{
        public static void main(String[] args){
                int i=0;
                System.out.println(i + "");
        }
}
//写法二:
public class Test2{
        public static void main(String[] args){
                int i=1;
                System.out.println(String.valueOf(1));
        }
}

单从写法上我是更倾向于第二种写法的,虽然多写几个字母但我认为这样更符合编码的习惯,毕竟➕一个空字符总感觉多了一些什么奇怪的东西。
但是这样说很苍白无力啊,谁也说服不了,为了证明我的喜好更好,来看看字节码。

zeal-pc:test zeal$ javap -c Test
Compiled from "Test.java"
public class Test {
  public Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0
       1: istore_1
       2: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       5: new           #3                  // class java/lang/StringBuilder
       8: dup
       9: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
      12: iload_1
      13: invokevirtual #5                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
      16: ldc           #6                  // String
      18: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      21: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      24: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      27: return
}

zeal-pc:test zeal$ javap -c Test2
Compiled from "Test2.java"
public class Test2 {
  public Test2();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_1
       1: istore_1
       2: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       5: iconst_1
       6: invokestatic  #3                  // Method java/lang/String.valueOf:(I)Ljava/lang/String;
       9: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      12: return
}

嗯,第一个比第二个长,我赢了。
还有就是,“+”在编译期会被用StringBuilder来实现这个想必大家都是知道的,从第一个可以看到代码执行了两次append方法,而第二个只是执行了一个valueOf方法。同时对比StringBuilder和String的源码可以发现append里面执行了一次getChars方法(ensureCapacityInternal数组拷贝这种情况并不会触发;append int是读表操作,append string是数组拷贝),valueOf里只是执行了一次getChars(读表)方法。

总结一下String.valueOf 速度更快,写法更优雅。

然而写法一在现在的多核多G机器上也并不会有啥影响。

上一篇下一篇

猜你喜欢

热点阅读