正如我之前的问题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是按值传递的吗? 因此,受对象引用影响的方法调用顺序与运行时类型一致也很重要。
答案 0 :(得分:0)
m.initMe(getint());
它指示调用由m。
现在如果m在执行之间引用一个新对象,虽然指令肯定会调用旧对象的方法。一旦完成,对象将无法访问,也将被收集。
答案 1 :(得分:0)
您会看到,在这里创建一个值为10的新MyClass
:
private static MyClass m = new MyClass(10);
现在,this.i
是10
,因为,你说它应该是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()
的调用,您可以m
在getint()
方法中引用新的对象引用。
但由于initMe()
在新作业之前被调用,this.i
会返回10
而不是20
。
在此之后,m
将i
值为20
的新对象引用为m.initMe(getint());
。如果您在第一个语句后添加另一行{{1}},那么您将从第二个语句执行中获得 20 。
因此,方法调用顺序也受到影响也很重要 对象引用与运行时类型对齐
因此,答案是是,订单确实很重要。