使用java对象引用的方法调用顺序

时间:2013-10-28 11:35:28

标签: java pass-by-reference pass-by-value

正如我之前的问题Java method invocation order

如果我的代码更改

public class MyClassTest {

    private static MyClass m = new MyClass(10);

    /**
     * @param args
     */
    public static void main(String[] args) {
        m.initMe(getint());
    }

    public static int getint() {
        m = new MyClass(20);
        return 40;
    }
}

class MyClass {
    private int i;

    public MyClass(int i) {
        this.i = i;
    }

    void initMe(int i) {
        System.out.println(this.i);
    }
}

我的输出是10而不是20导致Java是按值传递的吗? 因此,受对象引用影响的方法调用顺序与运行时类型一致也很重要。

4 个答案:

答案 0 :(得分:0)

m.initMe(getint());它指示调用由m。

引用的Object方法

现在如果m在执行之间引用一个新对象,虽然指令肯定会调用旧对象的方法。一旦完成,对象将无法访问,也将被收集。

答案 1 :(得分:0)

您会看到,在这里创建一个值为10的新MyClass

private static MyClass m = new MyClass(10);

现在,this.i10,因为,你说它应该是10

它不返回20的原因是因为你打电话时:

m.initMe(getint());

它将返回10,因为它是m来电时分配给initMe()的值。


如果你这样做:

public static void main(String[] args) {
        m = new MyClass(20);
        m.initMe(getint());
    }

    public static int getint() {
        return 40;
    }
你得到: 20,因为您在执行20之前已经为您的对象指定了值initMe()


有趣的是,如果你这样做:

  public static void main(String[] args) {
        m.initMe(getint());
        m.initMe(getint());
    }

    public static int getint() {
        m = new MyClass(20);
        return 40;
    }

你得到:

10
20

因为在第一次运行时,值为10,但m现在被分配了20的值,而对于下一次运行,在执行之前,它将保持价值20

答案 2 :(得分:0)

你如何回答上一个问题,JVM是一个基于堆栈的机器。首先运行静态部分,其中是MyClass(10)的初始化实例。在此之后,执行main(),其中MyClass(10)的实例将被推送到操作数堆栈(0: getstatic #2)。在此之后,将执行getint(),其中将创建MyClass(20)的新实例(6: invokespecial #6)并设置新的静态字段(9: putstatic #2),但在操作数中stack 仍然是旧值(MyClass(10))。

static {};
 Code:
   0: new           #5                  // class MyClass
   3: dup
   4: bipush        10
   6: invokespecial #6                  // Method MyClass."<init>":(I)V
   9: putstatic     #2                  // Field m:LMyClass;
  12: return
LineNumberTable:
  line 3: 0

public static void main(java.lang.String[]);
  Code:
   0: getstatic     #2                  // Field m:LMyClass;
   3: invokestatic  #3                  // Method getint:()I
   6: invokevirtual #4                  // Method MyClass.initMe:(I)V
   9: return
  LineNumberTable:
  line 7: 0
  line 8: 9

public static int getint();
  Code:
    0: new           #5                  // class MyClass
    3: dup
    4: bipush        20
    6: invokespecial #6                  // Method MyClass."<init>":(I)V
    9: putstatic     #2                  // Field m:LMyClass;
   12: bipush        40
   14: ireturn
  LineNumberTable:
   line 11: 0
   line 12: 12

答案 3 :(得分:-1)

执行以下行时会发生这种情况。

m.initMe(getint());
引用包含m值的对象的

10用于调用initMe()方法。现在发布initMe()的调用,您可以mgetint()方法中引用新的对象引用。

但由于initMe()在新作业之前被调用,this.i会返回10而不是20

在此之后,mi值为20的新对象引用为m.initMe(getint());。如果您在第一个语句后添加另一行{{1}},那么您将从第二个语句执行中获得 20


  

因此,方法调用顺序也受到影响也很重要   对象引用与运行时类型对齐

因此,答案是,订单确实很重要。