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

  • 相关阅读:
    【Uva 10618】Tango Tango Insurrection
    Scripting web services
    防止SQL注入式攻击的笔记
    Net中的Request和Response对象的理解
    Net中的Request和Response对象的理解
    Net中的Request和Response对象的理解
    UEditor编辑器第一次赋值失败的解决方法
    我不问+你不说
    我不问+你不说
    我不问+你不说
  • 原文地址:https://www.cnblogs.com/thewindkee/p/12873152.html
Copyright © 2011-2022 走看看