问题描述
public class MyClassTest {
private static MyClass m;
public static void main(String[] args) {
m.initMe(getint());
}
public static int getint() {
m = new MyClass();
return (int) Math.random()*100;
}
}
class MyClass{
int i;
void initMe(int i) {
this.i = i;
System.out.println(this.i);
}
}
此代码片段给出了 NullPointerException
,导致 initMe()
在调用 getint
之前被调用.这个问题的根本原因是什么?是 JAVA 传值,所以引用更新不受影响.
This code snippet gives NullPointerException
, causing initMe()
is invoked before getint
is invoked. What would be the root cause of this problem? Is JAVA pass-by-value so reference updation is not affected.
给我正确的理由.
推荐答案
一个编译器可以生成你想要的
A compiler could generate what you have in mind
- 为每个参数执行代码
- 将结果放入堆栈
- 调用方法(
m
将被初始化)
- execute the code for each parameter
- put the result on the stack
- call the method (
m
would be initialized)
但是 Java 规范 描述在评估参数之前必需的几个步骤.在知道如何处理参数之前,JVM 必须能够识别对象的类型(运行时类型).
But the Java specifications describe several steps that are necessary before evaluating the parameters. The JVM has to be able to identify the type of the object (the runtime type) before knowing how to handle the parameters.
这是生成的字节码
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
如您所见,第一步是在堆栈上加载 m
.它将加载空值.然后调用 getint
,它会设置 m
但 invokevirtual
使用的值将是已经加载到 JVM 堆栈上的值.
As you can see the first step is to load m
on the stack. It will load null. Then getint
is invoked, it will set m
but the value used by invokevirtual
will be the one already loaded on the JVM stack.
这篇关于Java方法调用顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!