zoukankan      html  css  js  c++  java
  • 【java基础】为何e1==(e1=e2)为false

    代码如下

    public class Exercise {
    	
    	static void print(Exercise e1,Exercise e2) {
    		System.out.println(e1==(e1=e2));
    	}
    	public static void main(String[] args) {
    		Exercise e1 = new Exercise();
    		Exercise e2 = new Exercise();
    		print(e1,e2);
    	}
    }

    编译后,使用javap 查看字节码

    javap -verbose Exercise.class

    参考指令:https://cs.au.dk/~mis/dOvs/jvmspec/ref-Java.html

    可以看出, 5行的时候,将第二个局部变量压入两次。

    6行的时候,弹出栈顶局部变量。 导致之后比较的时候,栈顶的两个引用不相同。 因此输出false.

    相关指令

    • 0x59 dup 复制栈顶数值并将复制值压入栈顶
    • 0x19 aload 将指定的引用类型本地变量推送至栈顶
    • 0x3a astore 将栈顶引用类型数值存入指定本地变量
    • 0xa0 if_icmpne 比较栈顶两int型数值大小, 当结果不等于0时跳转
    • 0xb6 invokevirtual 调用实例方法

    相关字节码

    D:	emp	est>javap -verbose Exercise.class
    Classfile /D:/temp/test/Exercise.class
      Last modified 2019-2-12; size 569 bytes
      MD5 checksum ca83d3f8fc84d49a8e6cec7faeb7b527
      Compiled from "Exercise.java"
    public class Exercise
      minor version: 0
      major version: 52
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #7.#21         // java/lang/Object."<init>":()V
       #2 = Fieldref           #22.#23        // java/lang/System.out:Ljava/io/PrintStream;
       #3 = Methodref          #24.#25        // java/io/PrintStream.println:(Z)V
       #4 = Class              #26            // Exercise
       #5 = Methodref          #4.#21         // Exercise."<init>":()V
       #6 = Methodref          #4.#27         // Exercise.print:(LExercise;LExercise;)V
       #7 = Class              #28            // java/lang/Object
       #8 = Utf8               <init>
       #9 = Utf8               ()V
      #10 = Utf8               Code
      #11 = Utf8               LineNumberTable
      #12 = Utf8               print
      #13 = Utf8               (LExercise;LExercise;)V
      #14 = Utf8               StackMapTable
      #15 = Class              #29            // java/io/PrintStream
      #16 = Class              #26            // Exercise
      #17 = Utf8               main
      #18 = Utf8               ([Ljava/lang/String;)V
      #19 = Utf8               SourceFile
      #20 = Utf8               Exercise.java
      #21 = NameAndType        #8:#9          // "<init>":()V
      #22 = Class              #30            // java/lang/System
      #23 = NameAndType        #31:#32        // out:Ljava/io/PrintStream;
      #24 = Class              #29            // java/io/PrintStream
      #25 = NameAndType        #33:#34        // println:(Z)V
      #26 = Utf8               Exercise
      #27 = NameAndType        #12:#13        // print:(LExercise;LExercise;)V
      #28 = Utf8               java/lang/Object
      #29 = Utf8               java/io/PrintStream
      #30 = Utf8               java/lang/System
      #31 = Utf8               out
      #32 = Utf8               Ljava/io/PrintStream;
      #33 = Utf8               println
      #34 = Utf8               (Z)V
    {
      public Exercise();
        descriptor: ()V
        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 3: 0
    
      static void print(Exercise, Exercise);
        descriptor: (LExercise;LExercise;)V
        flags: ACC_STATIC
        Code:
          stack=4, locals=2, args_size=2
             0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStrea
             3: aload_0
             4: aload_1
             5: dup
             6: astore_0
             7: if_acmpne     14
            10: iconst_1
            11: goto          15
            14: iconst_0
            15: invokevirtual #3                  // Method java/io/PrintStream.println:(Z)V
            18: return
          LineNumberTable:
            line 6: 0
            line 7: 18
          StackMapTable: number_of_entries = 2
            frame_type = 78 /* same_locals_1_stack_item */
              stack = [ class java/io/PrintStream ]
            frame_type = 255 /* full_frame */
              offset_delta = 0
              locals = [ class Exercise, class Exercise ]
              stack = [ class java/io/PrintStream, int ]
    
      public static void main(java.lang.String[]);
        descriptor: ([Ljava/lang/String;)V
        flags: ACC_PUBLIC, ACC_STATIC
        Code:
          stack=2, locals=3, args_size=1
             0: new           #4                  // class Exercise
             3: dup
             4: invokespecial #5                  // Method "<init>":()V
             7: astore_1
             8: new           #4                  // class Exercise
            11: dup
            12: invokespecial #5                  // Method "<init>":()V
            15: astore_2
            16: aload_1
            17: aload_2
            18: invokestatic  #6                  // Method print:(LExercise;LExercise;)V
            21: return
          LineNumberTable:
            line 10: 0
            line 11: 8
            line 12: 16
            line 13: 21
    }
    SourceFile: "Exercise.java"

    PS:个人理解,欢迎指正。

    参考

    JVM 虚拟机字节码指令表

    Java Virtual Machine Online Instruction Reference

  • 相关阅读:
    形象理解ERP(转)
    禁用windows server 2008 域密码复杂性要求策略
    How to adding find,filter,remove filter on display method Form
    Windows Server 2008 R2激活工具
    How to using bat command running VS development SSRS report
    Creating Your First Mac AppGetting Started
    Creating Your First Mac AppAdding a Track Object 添加一个 Track 对象
    Creating Your First Mac AppImplementing Action Methods 实现动作方法
    Creating Your First Mac AppReviewing the Code 审查代码
    Creating Your First Mac AppConfiguring the window 设置窗口
  • 原文地址:https://www.cnblogs.com/thewindkee/p/12873152.html
Copyright © 2011-2022 走看看