码迷,mamicode.com
首页 > 编程语言 > 详细

Javac背后的故事——空类

时间:2015-04-10 18:13:50      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:

Javac背后的故事——空类


转载时请以超链接形式标明文章原始出处和作者信息及本声明

http://www.blogbus.com/dreamhead-logs/5999838.html


程序员最熟悉的是源代码,但是要让程序真正的发挥功效,少不了编译器的帮助。javac的作用就是将Java代码编译为JVM指令。由于Java语言和JVM同出一门,所以,稍微熟悉一下,我们便不难发现,二者几乎是直接对应的。当然,为了简化代码的编写,javac除了直接翻译之外,还暗地里帮我们做了不少工作,我们从最简单的情况看起。

public class Test {
}

我们用javac编译这段代码,javap可以帮助我们反编译生成的类文件。

javap -c Test

下面就是反编译的结果。

public class Test extends java.lang.Object{
public Test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return
}


抛开指令具体的内容,上面反编译的结果清清楚楚的告诉我们,我们编写的这个空类一点都不空,因为其中还有一个构造函数。这就是javac替我们做的工作。没错,这是javac做的,但未必是JVM要求的。其实,JVM上运行的类,完全可以没有构造函数。不过,前面的例子已经明明白白的告诉我们,因为javac的作用,直接用Java语言是无法构造出真正的空类。那我们就不妨直接从字节码入手,借助ObjectWeb ASM构造真正的“空“类。

public class NoCtorGenerator {
    public static void main(String[] args) throws Exception {
        String className = "NoCtor";
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        cw.visit(Opcodes.V1_2, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", null);
        cw.visitEnd();
        
        try {
            os = new FileOutputStream(className + ".class");
            os.write(cw.toByteArray());
        } finally {
            if (os != null) {
                os.close();
            }
        }
    }
}

借助javap,我们可以看到生成的结果,确实没有构造函数。

public class NoCtor extends java.lang.Object{
}

不过,因为没有构造函数存在,我们并不能用这个类创建对象,但是,下面的代码证明了这个类生成的类确实可用。

public class NoCtorMain {
    public static void main(String[] args) {
        System.out.println(NoCtor.class);
    }
}

运行这段代码,我们可以得到下面的输出:

class NoCtor


Javac背后的故事——空类

标签:

原文地址:http://my.oschina.net/xinxingegeya/blog/398688

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!