标签:
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
标签:
原文地址:http://my.oschina.net/xinxingegeya/blog/398688