0

作为我之前的问题Java 方法调用顺序

如果我的代码更改

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

4 回答 4

0

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

m.initMe(getint());它指示调用m引用的Object的方法。

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

于 2013-10-28T11:38:35.480 回答
0

你看,在这里你创建了MyClass一个值为 10 的新的:

private static MyClass m = new MyClass(10);

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

它不返回的原因20是因为当您调用时:

m.initMe(getint());

它将返回,因为它是调用时10分配的值。minitMe()


如果你这样做:

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被分配了20now 的值,而对于下一次运行,在执行之前,它将保持值20

于 2013-10-28T12:02:51.730 回答
-1

这就是执行以下行时发生的情况。

m.initMe(getint());

m这是指包含10值的对象用于调用initMe()方法。现在发布 的调用initMe(),您m在方法中引用一个新的对象引用getint()

但由于在initMe()新分配之前调用了 ,因此this.i返回10而不是20.

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


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

因此,答案是Yes,顺序很重要。

于 2013-10-28T11:40:28.940 回答