这一很简单的甚至很无聊的问题竟然这么火,奇怪。
我更无聊,写下自己的看法,并散分。
首先代码:public class Main { public static void main(String[] args) {
Test test = new Test();
}
}class Test { public Test() {
}
}很简单,main 方法中就是创建了一个Test类的对象,下面看看编译之后的bytecode是什么样子的:
Main.class>Compiled from "Main.java"
public class Main extends java.lang.Object{
public Main();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: returnpublic static void main(java.lang.String[]);
Code:
0: new #2; //class Test ,去常数池读取Test的#2位置读取Test类的CONSTANT_Class信息,分配内存,得到分配后的引用,压入操作数栈
3: dup //复制操作数栈顶的字,这里就是复制new得到的引用,供调用<init>方法使用
4: invokespecial #3; //Method Test."<init>":()V 调用构造方法
7: astore_1 //将栈顶的引用存入局部变量,就是实现源代码中的把新对象的引用赋值给test
8: return //方法结束
}按照指令的解释,new 指令不彻底创建新实例,新实例直到在为初始化的实例上调用了实例初始化方法时,才彻底创建。
类Test的实例初始化方法 (init)把新的未初始化的对象看作它在局部变量0中的this参数。在它被允许对this做任何事情之前必须对this对象或者调用该类的一个替换的实例初始化方法,或者调用一个超类的初始化方法。
4: invokespecial #3; //Method Test."<init>":()V
这句是对Test的构造方法的调用,去看Test.class的内容:Compiled from "Main.java"
class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V 调用父类的构造方法
4: return //方法结束
}Test类的构造方法很简单,就是调用父类Object的构造方法。执行完毕,方法返回。
return指令用于从声明为void的方法返回。
方法返回指令由返回类型区分,ireturn,lreturn,freturn,dreturn和areturn。前面四个表示四种基本类型,areturn表示引用类型。
可见这里处理是类似于void方法的。基本就这些内容。
新手上路,大家轻拍。
我更无聊,写下自己的看法,并散分。
首先代码:public class Main { public static void main(String[] args) {
Test test = new Test();
}
}class Test { public Test() {
}
}很简单,main 方法中就是创建了一个Test类的对象,下面看看编译之后的bytecode是什么样子的:
Main.class>Compiled from "Main.java"
public class Main extends java.lang.Object{
public Main();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: returnpublic static void main(java.lang.String[]);
Code:
0: new #2; //class Test ,去常数池读取Test的#2位置读取Test类的CONSTANT_Class信息,分配内存,得到分配后的引用,压入操作数栈
3: dup //复制操作数栈顶的字,这里就是复制new得到的引用,供调用<init>方法使用
4: invokespecial #3; //Method Test."<init>":()V 调用构造方法
7: astore_1 //将栈顶的引用存入局部变量,就是实现源代码中的把新对象的引用赋值给test
8: return //方法结束
}按照指令的解释,new 指令不彻底创建新实例,新实例直到在为初始化的实例上调用了实例初始化方法时,才彻底创建。
类Test的实例初始化方法 (init)把新的未初始化的对象看作它在局部变量0中的this参数。在它被允许对this做任何事情之前必须对this对象或者调用该类的一个替换的实例初始化方法,或者调用一个超类的初始化方法。
4: invokespecial #3; //Method Test."<init>":()V
这句是对Test的构造方法的调用,去看Test.class的内容:Compiled from "Main.java"
class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V 调用父类的构造方法
4: return //方法结束
}Test类的构造方法很简单,就是调用父类Object的构造方法。执行完毕,方法返回。
return指令用于从声明为void的方法返回。
方法返回指令由返回类型区分,ireturn,lreturn,freturn,dreturn和areturn。前面四个表示四种基本类型,areturn表示引用类型。
可见这里处理是类似于void方法的。基本就这些内容。
新手上路,大家轻拍。
Object o = new Object();o=null;//收回空间,丢失对象,丢失了对象的指针
当然o还是存在的.
接分。
You might notice on closer inspection of the bytecode that certain opcodes are prefixed with an `a' or an `i'. For example, in the Employee class constructor you see aload_0 and iload_2. The prefix is representative of the type that the opcode is working with. The prefix `a' means that the opcode is manipulating an object reference. The prefix `i' means the opcode is manipulating an integer. Other opcodes use `b' for byte, `c' for char, `d' for double, etc. This prefix gives you immediate knowledge about what type of data is being manipulated.http://blog.csdn.net/l1j5n/archive/2006/03/01/613044.aspx
比看The Java Virtual Machine Specification舒服多了。
直接
javap -c Main
就得到了。
或者直接存到一个文件里
javap -c Main >main.txtjavap是jdk中的工具。
个人认为,没必要去钻这个牛角尖,有些东西并不是我们作为程序员所要理解的东西。当然这是个人看法,欢迎探讨
有道理,对开发没有提高。
我只是对编译原理感兴趣。