dyerac  
dyerac In Java
公告

日历
<2007年8月>
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678
统计
  • 随笔 - 36
  • 文章 - 10
  • 评论 - 94
  • 引用 - 0

导航

常用链接

留言簿(5)

随笔分类(49)

随笔档案(36)

文章分类(11)

文章档案(10)

相册

dyerac

搜索

  •  

积分与排名

  • 积分 - 78537
  • 排名 - 707

最新随笔

最新评论

阅读排行榜

评论排行榜

 
要让Java这个面向“对象”的世界正常运作,创建对象就是一项不可或缺的操作。

public class NewMain {
    public static void main(String[] args) {
        new Object();
    }
}

用javap反编译上面的代码,我们可以得到下面的指令,这里省去了javac暗中创建的构造函数。

public class NewMain extends java.lang.Object{
    ...
public static void main(java.lang.String[]);
  Code:
   0:   new     #3; //class java/lang/Object
   3:   invokespecial   #8; //Method java/lang/Object."<init>":()V
   6:   return
}

从这段代码中,我们可以清晰的看出创建对象(new)和调用构造函数(invokespecial)两个过程。关于这个问题,我在《对象的生命》中曾经进行过讨论。

既然javac将一个new的动作被解释为两条指令,那在JVM的层面上,我们当然就可以将它们分开。下面是一段没什么实际用途的代码,只是证明这个观点可行性。

public class NewGenerator {
    public static void main(String[] args) throws Exception {
        String className = "New";
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        cw.visit(Opcodes.V1_2, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", null);
        Method m = Method.getMethod("void main (String[])");
        GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, m, null, null, cw);
        mg.newInstance(Type.getType(Object.class));
        Label label = mg.newLabel();
        mg.ifNonNull(label);
        mg.mark(label);
        mg.getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class));
        mg.push("new object is not null");
        mg.invokeVirtual(Type.getType(PrintStream.class), Method.getMethod("void println(java.lang.String)"));
        mg.pop();
        mg.returnValue();
        mg.endMethod();
        cw.visitEnd();

        OutputStream os = null;
        try {
            os = new FileOutputStream(className + ".class");
            os.write(cw.toByteArray());
        } finally {
            if (os != null) {
                os.close();
            }
        }
    }
}

这段代码生成的类是能够运行的,有兴趣的可以自己试一下。这段代码的作用是new出一个对象之后,如果这个对象非空的话,就会产生一个输出:
    new object is not null

当然,如果尝试用这个对象做一些其它的操作,会有错误等待着我们,因为这个对象并不是一个完整的对象。在JVM规范中有相关的解释:new指令并不能完整创建出一个新的对象,直到对未初始化的对象调用了实例初始化方法才会完成实例的创建。这段代码也正好符合《对象的生命》中的解释,它只是负责做出申请内存。当然,在JVM中,它的实际工作要略多一些,如果这个对象的类没有加载,就会加载相应的类。
posted on 2007-08-13 18:52 dyerac in java... 阅读(361) 评论(0)  编辑  收藏 所属分类: JavaSE

只有注册用户登录后才能发表评论。


网站导航:
 
 
Copyright © dyerac in java... Powered by: 博客园 模板提供:沪江博客