美文网首页
从字节码看为什么说java都是值传递

从字节码看为什么说java都是值传递

作者: 上重楼 | 来源:发表于2018-05-12 11:56 被阅读4次

先上源码

public class TestRef {

    public int id = 1;


    public static void main(String[] args) {
        int a = 10;
        String b = "a";
        TestRef c = new TestRef();

        change(a);
        change(b);
        change(c);
        changeRef(c);


    }

    public static void change(int a) {
        a = 20;
    }

    public static void change(String b) {
        b = "c";
    }

    public static void change(TestRef c) {
        c = new TestRef();
    }


    public static void changeRef(TestRef c) {
        c.id = 10;
    }
}

再上字节码:

public class TestRef {
  public int id;

  public TestRef();
    Code:
       0: aload_0                            //将this载入栈顶
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V 
       4: aload_0                           //再次将this载入栈顶,因为上面那行invokespecial已经消耗掉第一行的this去实例化对象了
       5: iconst_1                          //将常量值1推入栈顶
       6: putfield      #2                  // Field id:I  //设置偏移4那行推入的this的#2变量的值为偏移5那行所推入的值
       9: return

  public static void main(java.lang.String[]);
    Code:
       0: bipush        10
       2: istore_1
       3: ldc           #3                  // String a
       5: astore_2
       6: new           #4                  // class TestRef
       9: dup
      10: invokespecial #5                  // Method "<init>":()V
      13: astore_3
      14: iload_1
      15: invokestatic  #6                  // Method change:(I)V
      18: aload_2
      19: invokestatic  #7                  // Method change:(Ljava/lang/String;)V
      22: aload_3
      23: invokestatic  #8                  // Method change:(LTestRef;)V
      26: aload_3
      27: invokestatic  #9                  // Method changeRef:(LTestRef;)V
      30: return

  public static void change(int);
    Code:
       0: bipush        20
       2: istore_0
       3: return

  public static void change(java.lang.String);
    Code:
       0: ldc           #10                 // String c
       2: astore_0
       3: return

  public static void change(TestRef);
    Code:
       0: new           #4                  // class TestRef
       3: dup
       4: invokespecial #5                  // Method "<init>":()V
       7: astore_0
       8: return

  public static void changeRef(TestRef);
    Code:
       0: aload_0        //将参数载入栈
       1: bipush        10    //推入一个10
       3: putfield      #2                  // Field id:I  //设置参数的#2实例变量的值为10
       6: return
}

3个change(T)方法都是错误的使用例子,从字节码可以看到基本都是在操作方法自身的局部变量表,方法的参数都是一个对象引用(或者说指向对象内容的指针副本) 修改也只是将指针的值改变,而非指针指向的值

changeRef方法第一行就是 aload_0这个和构造函数第一行一样,都是将this载入栈顶
而this是一个指向对象的引用(指针)。
在main方法偏移26那行,aload_3 是将局部变量表slot 3 的的对象引用复制到栈顶,这样从旁证明了,java传递对象的时候传递的是对象的引用的副本 对象的引用是4个字节(操作数栈和局部变量表 都是一个单位等于4个字节 基本类型除了 double long之外其他都是一个单位)这也从旁佐证 方法调用传递的是对象引用副本

相关文章

  • 从字节码看为什么说java都是值传递

    先上源码 再上字节码: 3个change(T)方法都是错误的使用例子,从字节码可以看到基本都是在操作方法自身的局部...

  • 详解 JVM 字节码(2)

    什么是字节码,为什么需要字节码编译 JVM 编译成机器码, 我们看一看 Java 编译过程 java 源码 编译为...

  • 深度好文

    为什么说Java中只有值传递

  • 字节码引用检测原理与实战

    一、字节码与引用检测 1.1 Java字节码 本章中的字节码重点研究Java 字节码,Java字节码(Java b...

  • Java 与值传递

    问: 什么是值传递?什么是引用传递?为什么说 Java 中只有值传递? 一、值传递与引用传递 实参与形参: 实际参...

  • 可爱的字节码&修改

    1.为什么要修改字节码 字节码是java多平台运行的根本原因,程序运行的状态和结果都由字节码决定。所以控制了字节码...

  • JavaAgent 与 动态代理

    ASM, CGlib, Java Proxy, Javassist都是可以操作字节码,但是这些操作字节码都需要等到...

  • Java 基础技术

    Java 函数调用是传值还是传引用?从字节码角度来看看 ! 为 Java 程序员而生的 10 + 最佳库 Redd...

  • 聊聊Java内部类

    一.磨叽磨叽Java值传递与引用传递 “在Java里面参数传递都是按值传递”即:按值传递是传递的值的拷贝,按引用传...

  • 程序员练级攻略(2018):Java底层知识

    Java 字节码相关 首先,Java 最黑科技的玩法就是字节码编程,也就是动态修改或是动态生成 Java 字节码。...

网友评论

      本文标题:从字节码看为什么说java都是值传递

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