美文网首页Java学习笔记
这个太简单了,我也不会

这个太简单了,我也不会

作者: chenmingang | 来源:发表于2018-03-19 22:47 被阅读17次

    假设 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机器上也并不会有啥影响。

    相关文章

      网友评论

        本文标题:这个太简单了,我也不会

        本文链接:https://www.haomeiwen.com/subject/vvsmqftx.html