美文网首页
面试题汇总

面试题汇总

作者: 穆木小七 | 来源:发表于2018-03-27 11:30 被阅读5次

    1、下面程序输出结果:

    public class Demo{
        public static void main(String[] args) throws Exception {
            String s1 = "ab";
            String s2 = "abc";
            String s3 = s1 + "c";
            System.out.println(s3==s2);//true
        }
    }
    

    分析:s1 s2都会在常量池中创建对象,s3是变量s1和常量"c"拼接而来,通过javap命令 可以看到具体实现步骤.

    //编译要生成所有调试信息
    javac -g Demo.java
    //反编译
    javap -v Demo
    

    使用javap命令结果如下:

    Classfile /C:/Users/Desktop/Demo.class
      Last modified 2018-3-27; size 907 bytes
      MD5 checksum d10a17ec64e71338de935811f6abbb35
      Compiled from "Demo.java"
    public class Demo
      SourceFile: "Demo.java"
      minor version: 0
      major version: 51
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool://常量池
       #1 = Methodref          #12.#36        //  java/lang/Object."<init>":()V
       #2 = String             #37            //  ab
       #3 = String             #38            //  abc
       #4 = Class              #39            //  java/lang/StringBuilder
       #5 = Methodref          #4.#36         //  java/lang/StringBuilder."<init>":()V
       #6 = Methodref          #4.#40         //  java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
       #7 = String             #41            //  c
       #8 = Methodref          #4.#42         //  java/lang/StringBuilder.toString:()Ljava/lang/String;
       #9 = Fieldref           #43.#44        //  java/lang/System.out:Ljava/io/PrintStream;
      #10 = Methodref          #45.#46        //  java/io/PrintStream.println:(Z)V
      #11 = Class              #47            //  Demo
      #12 = Class              #48            //  java/lang/Object
      #13 = Utf8               <init>
      #14 = Utf8               ()V
      #15 = Utf8               Code
      #16 = Utf8               LineNumberTable
      #17 = Utf8               LocalVariableTable
      #18 = Utf8               this
      #19 = Utf8               LDemo;
      #20 = Utf8               main
      #21 = Utf8               ([Ljava/lang/String;)V
      #22 = Utf8               args
      #23 = Utf8               [Ljava/lang/String;
      #24 = Utf8               s1
      #25 = Utf8               Ljava/lang/String;
      #26 = Utf8               s2
      #27 = Utf8               s3
      #28 = Utf8               StackMapTable
      #29 = Class              #23            //  "[Ljava/lang/String;"
      #30 = Class              #49            //  java/lang/String
      #31 = Class              #50            //  java/io/PrintStream
      #32 = Utf8               Exceptions
      #33 = Class              #51            //  java/lang/Exception
      #34 = Utf8               SourceFile
      #35 = Utf8               Demo.java
      #36 = NameAndType        #13:#14        //  "<init>":()V
      #37 = Utf8               ab
      #38 = Utf8               abc
      #39 = Utf8               java/lang/StringBuilder
      #40 = NameAndType        #52:#53        //  append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      #41 = Utf8               c
      #42 = NameAndType        #54:#55        //  toString:()Ljava/lang/String;
      #43 = Class              #56            //  java/lang/System
      #44 = NameAndType        #57:#58        //  out:Ljava/io/PrintStream;
      #45 = Class              #50            //  java/io/PrintStream
      #46 = NameAndType        #59:#60        //  println:(Z)V
      #47 = Utf8               Demo
      #48 = Utf8               java/lang/Object
      #49 = Utf8               java/lang/String
      #50 = Utf8               java/io/PrintStream
      #51 = Utf8               java/lang/Exception
      #52 = Utf8               append
      #53 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
      #54 = Utf8               toString
      #55 = Utf8               ()Ljava/lang/String;
      #56 = Utf8               java/lang/System
      #57 = Utf8               out
      #58 = Utf8               Ljava/io/PrintStream;
      #59 = Utf8               println
      #60 = Utf8               (Z)V
    {
      public Demo();
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: return
          LineNumberTable:
            line 1: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                   0       5     0  this   LDemo;
    
      public static void main(java.lang.String[]) throws java.lang.Exception;
        flags: ACC_PUBLIC, ACC_STATIC
        Code:
          stack=3, locals=4, args_size=1
             //ldc命令:把常量池中的项压入栈
             0: ldc           #2                  // String ab
             2: astore_1
             3: ldc           #3                  // String abc
             5: astore_2
             6: new           #4                  // class java/lang/StringBuilder
             9: dup
            10: invokespecial #5                  // Method java/lang/StringBuilder."<init>":()V
            13: aload_1
            14: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
            17: ldc           #7                  // String c
            19: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
            22: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
            25: astore_3
            26: getstatic     #9                  // Field java/lang/System.out:Ljava/io/PrintStream;
            29: aload_3
            30: aload_2
            31: if_acmpne     38 //如果判断为true,跳转38行
            34: iconst_1 //也就是false
            35: goto          39
            38: iconst_0
            39: invokevirtual #10                 // Method java/io/PrintStream.println:(Z)V
            42: return
          LineNumberTable:
            line 3: 0
            line 4: 3
            line 5: 6
            line 6: 26
            line 7: 42
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                   0      43     0  args   [Ljava/lang/String;
                   3      40     1    s1   Ljava/lang/String;
                   6      37     2    s2   Ljava/lang/String;
                  26      17     3    s3   Ljava/lang/String;
          StackMapTable: number_of_entries = 2
               frame_type = 255 /* full_frame */
              offset_delta = 38
              locals = [ class "[Ljava/lang/String;", class java/lang/String, class java/lang/String, class java/lang/String ]
              stack = [ class java/io/PrintStream ]
               frame_type = 255 /* full_frame */
              offset_delta = 0
              locals = [ class "[Ljava/lang/String;", class java/lang/String, class java/lang/String, class java/lang/String ]
              stack = [ class java/io/PrintStream, int ]
    
        Exceptions:
          throws java.lang.Exception
    }
    

    在main方法下面可以看出,String s1 = "ab",底层就是把"ab"字符串从常量池中拿出来赋给s1变量,而s3是通过创建StringBuilder对象.append()方法进行连接,然后调用toString()再赋值给s3变量,此时字符串"abc"对象在堆内存中,故判断s1 == s3为false.

    一些概念解释:
    常量池:
    在编译器被确定,并保存在已编译的.class字节码文件中的一些数据,它包括关于类,方法,接口中的常量.也包括字符串直接量.
    直接量:
    指在程序中通过源代码直接给出的值.如:

    String s1 = "hello";
    String s2 = "he" + "llo";
    s1 == s2 //true
    

    原因:"he"和"llo"都是字符串常量,当一个字符串由多个字符串常量连接而成时,他本身也就是字符串常量,s2同样在编译期就被解析为一个字符串常量,故为true.

    相关文章

      网友评论

          本文标题:面试题汇总

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