﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-Java学习之路</title><link>http://www.blogjava.net/zxt/</link><description>墙上芦苇，头重脚轻根底浅；山间竹笋，嘴尖皮厚腹中空。</description><language>zh-cn</language><lastBuildDate>Thu, 23 Apr 2026 22:59:17 GMT</lastBuildDate><pubDate>Thu, 23 Apr 2026 22:59:17 GMT</pubDate><ttl>60</ttl><item><title>读书笔记：java的class文件格式分析（一）</title><link>http://www.blogjava.net/zxt/archive/2009/03/23/261487.html</link><dc:creator>Zang XT</dc:creator><author>Zang XT</author><pubDate>Mon, 23 Mar 2009 04:20:00 GMT</pubDate><guid>http://www.blogjava.net/zxt/archive/2009/03/23/261487.html</guid><wfw:comment>http://www.blogjava.net/zxt/comments/261487.html</wfw:comment><comments>http://www.blogjava.net/zxt/archive/2009/03/23/261487.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zxt/comments/commentRss/261487.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zxt/services/trackbacks/261487.html</trackback:ping><description><![CDATA[<blockquote> <p>阅读Java Virtual Machine Specification中的第四章，理解Java的class文件格式。</p> <p>class文件由8位的字节流组成。</p> <p>The ClassFile Structure</p> <p>ClassFile{</p> <p>u4 magic;</p> <p>u2 minor_version;</p> <p>u2 major_version;</p> <p>u2 constant_pool_count;</p> <p>cp_info constant_pool[constant_pool_count-1];</p> <p>u2 access_flags;</p> <p>u2 this_class;</p> <p>u2 interfaces_count;</p> <p>u2 interfaces[interfaces_count];</p> <p>u2 fields_count;</p> <p>field_info fields[fields_count];</p> <p>u2 methods_count;</p> <p>method_info methods[methods_count];</p> <p>u2 attributes_count;</p> <p>attribute_info attributes[attrributes_count];</p> <p>}</p> <p>说明：u2表示无符号2字节量，u4表示无符号4字节量。</p> <p>各字段的说明：</p> <p>magic</p> <p>一般二进制文件中都有magic number这一项，这个数说明该文件是一个class文件，它的值是0xcAFEBABE。</p> <p>minor_version,major_version</p> <p>class文件的版本号。</p> <p>constant_pool_count </p> <p>常量池表中项目数加1得到。从后面的cp_info constant_pool[constant_pool_count-1];也容易理解这个值的意思。</p> <p>cp_info constant_pool[]</p> <p>存储该class文件中使用到的常量信息。</p> <p>access_flag</p> <p>说明该class文件的访问权限和相关属性，通过位掩码来设定。</p> <table style="width: 400px" cellspacing="0" cellpadding="2" border="1"> <tbody> <tr> <td valign="top" width="133">Flag Name</td> <td valign="top" width="133">值</td> <td valign="top" width="133">解释</td></tr> <tr> <td valign="top" width="133">ACC_PUBLIC</td> <td valign="top" width="133">0x0001</td> <td valign="top" width="133">public</td></tr> <tr> <td valign="top" width="133">ACC_FINAL</td> <td valign="top" width="133">0x0010</td> <td valign="top" width="133">final</td></tr> <tr> <td valign="top" width="133">ACC_SUPER</td> <td valign="top" width="133">0x0020</td> <td valign="top" width="133">跟调用invokespecial指令时的处理有关</td></tr> <tr> <td valign="top" width="133">ACC_INTERFACE</td> <td valign="top" width="133">0x0200</td> <td valign="top" width="133">这是个接口</td></tr> <tr> <td valign="top" width="133">ACC_ABSTRACT</td> <td valign="top" width="133">0x0400</td> <td valign="top" width="133">abastract</td></tr> <tr> <td valign="top" width="133">ACC_SYNTHETIC</td> <td valign="top" width="133">0x1000</td> <td valign="top" width="133">没有在源代码中出现，该类是编译器生成的</td></tr> <tr> <td valign="top" width="133">ACC_ANNOTATION</td> <td valign="top" width="133">0x2000</td> <td valign="top" width="133">注解类型</td></tr> <tr> <td valign="top" width="133">ACC_ENUM</td> <td valign="top" width="133">0x4000</td> <td valign="top" width="133">枚举类型</td></tr></tbody></table> <p>&nbsp;</p> <p>这些属性都很容易理解，比如我们定义一个类public final Test{},则Test.class的access_flag中，ACC_PUBLIC和ACC_FINAL是置位的，而ACC_INTERFACE一项肯定是0。很多类似的组合规则倒是容易自己总结出来，比如如果ACC_INTERFACE置位了，那肯定ACC_ABSTRACT也是置位的，因为接口肯定是抽象的；如果ACC_ANNOTATION置位了，那ACC_ANNOTATION肯定同时置位，等等，诸如此类。</p> <p>画一个具体的位示意图表示：</p> <p><a href="http://www.blogjava.net/images/blogjava_net/zxt/WindowsLiveWriter/javaclass_EA43/image_2.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="120" alt="image" src="http://www.blogjava.net/images/blogjava_net/zxt/WindowsLiveWriter/javaclass_EA43/image_thumb.png" width="244" border="0"></a> </p> <p>this_class </p> <p>一个下标，指向常量池表中代表当前类的Constant_Class_info。</p> <p>super_class</p> <p>为0，或者为一个下标，指向常量池中代表其父类的Constant_Class_info。如果这个值为0，那么当前类肯定是Object类。如果当前类是一个接口，该下标指向的是Object类的描述信息。</p> <p>interface_count</p> <p>该类实现的接口数，或者该接口实现的超接口数。</p> <p>interfaces[]</p> <p>具体的接口信息，每一项都是常量池表中的一个下标，指向表示接口的Constant_Class_info。</p> <p>后面几个依次是字段（field），方法（methods）和属性的描述，不再赘述，</p></blockquote> <p>&nbsp;</p> <blockquote> <p>下面具体的分析一个class文件。源文件很简单：</p> <p>public class Test{ <br>public static void main(String[] args){ <br>System.out.println("Hello World!"); <br>} <br>}</p> <p>&nbsp;</p> <p>编译，得到Test.class文件，使用WinHex打开。</p> <p><a href="http://www.blogjava.net/images/blogjava_net/zxt/WindowsLiveWriter/javaclass_EA43/image_4.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="242" alt="image" src="http://www.blogjava.net/images/blogjava_net/zxt/WindowsLiveWriter/javaclass_EA43/image_thumb_1.png" width="244" border="0"></a> </p> <p>前4个字节是magic部分，内容为0xCAFEBABE;随后的4个字节是class文件的版本号，这里主版本号是0x0032，也就是50，这是使用jdk1.6编译出的class文件。再后面的2个字节是常量池表的大小信息，0x001D，也就是29，说明常量池表中一共有28项。为了方便观察，可以使用javap -verbose Test得到的结果和当前的二进制文件进行对比。</p> <p>入门到此，以后继续。</p></blockquote><img src ="http://www.blogjava.net/zxt/aggbug/261487.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zxt/" target="_blank">Zang XT</a> 2009-03-23 12:20 <a href="http://www.blogjava.net/zxt/archive/2009/03/23/261487.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习目标</title><link>http://www.blogjava.net/zxt/archive/2009/03/21/261225.html</link><dc:creator>Zang XT</dc:creator><author>Zang XT</author><pubDate>Sat, 21 Mar 2009 10:28:00 GMT</pubDate><guid>http://www.blogjava.net/zxt/archive/2009/03/21/261225.html</guid><wfw:comment>http://www.blogjava.net/zxt/comments/261225.html</wfw:comment><comments>http://www.blogjava.net/zxt/archive/2009/03/21/261225.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zxt/comments/commentRss/261225.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zxt/services/trackbacks/261225.html</trackback:ping><description><![CDATA[<blockquote> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 以一种玩的心态学习java，关注java的编译实现和java虚拟机原理，暂时不去关注java相关的各种应用。目标不能太多，更不能太高，切忌！ <br>几个具体的，可操作的目标： <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class文件格式分析。根据jvm规范中的定义，理解class文件结构，能自己写一个分析工具；分析javap的源代码。&nbsp; 深入学习编译原理，分析javac的源代码。以前分析过一小部分，但不够深入。 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 研究多线程编程模型，有几本书重点的看一下，《unix网络编程》，《面向模式的软件体系结构卷2：用于并发和网络化对象的模式》，《PATTERN-ORIENTED SOFTWARE ARCHITECTURE A Pattern Language for Distributed Computing》，《Java Concurrency in Practice》。 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; openjdk已经在Ubuntu上构建成功，可以考虑进行一些跟踪和调试分析。</p></blockquote><img src ="http://www.blogjava.net/zxt/aggbug/261225.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zxt/" target="_blank">Zang XT</a> 2009-03-21 18:28 <a href="http://www.blogjava.net/zxt/archive/2009/03/21/261225.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>