﻿<?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/baogenfly/category/16795.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 03:47:33 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 03:47:33 GMT</pubDate><ttl>60</ttl><item><title>[转载+修改]分析Java .class文件</title><link>http://www.blogjava.net/baogenfly/articles/78557.html</link><dc:creator>王某某</dc:creator><author>王某某</author><pubDate>Wed, 01 Nov 2006 13:30:00 GMT</pubDate><guid>http://www.blogjava.net/baogenfly/articles/78557.html</guid><wfw:comment>http://www.blogjava.net/baogenfly/comments/78557.html</wfw:comment><comments>http://www.blogjava.net/baogenfly/articles/78557.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/baogenfly/comments/commentRss/78557.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/baogenfly/services/trackbacks/78557.html</trackback:ping><description><![CDATA[
		<font size="2">看了第6章的java class文件这一部分，我觉得对class文件有进一步的了解。于是想作一点笔记，以备以后查时方便。<br />      这章的一个例子虽然简单，但是我觉的很有一定代表性。例子如下：<br /><br />1：class Act {<br />2：   public static void doMathForever(int m) {<br />3：      int i = 0;<br />4：     int n=4&gt;3?1:0;<br />5：        for (;;) {<br />6：           i += 1;<br />7：            i *= 2;<br />8：       }<br />9：    }<br />10：}<br /><br /><br />我用javap -verbose Act查看，代码如下：（红色为自己加上的注解）<br />Compiled from "Act.java"     <br /><font style="BACKGROUND-COLOR: #ff0000">因为编译原文件不一定必须与java语言相关，可以使用其他语言来编写程序，然后将其编译为class文件，所以这里要写上Act.java而不是Act. 呵呵，想来以前为什么javac 来编译源文件时一定要加.java，而java 执行时就不需要加.java了，当时就是搞不懂，现在明白了。</font><br />class Act extends java.lang.Object<br />  SourceFile: "Act.java"<br /><font style="BACKGROUND-COLOR: #ff0000">SourceFile属性，它提供了产生class文件的源文件的名称，它是一个可选的项，为什么说它是可选项的，因为class可以自己用UE等工具写。</font><br />  minor version: 0<br />  major version: 49<br /><font style="BACKGROUND-COLOR: #ff0000">版本号：我用的是5.0的，出来的major version 是49，书上说1.0或1.2是45，1.4我想可能是48 吧。呵呵，还没有试过。</font><br />  Constant pool:<br /></font>
		<font size="2">
				<font style="BACKGROUND-COLOR: #ff0000">这个是常量池，刚看书的时候我还以为常量池放的一定是常量。错。<br />常量池就是该类型所用常量的一个有序集合，包括直接常量(String,integer,floating  point常量）和对其他类型、字段和方法的符号引用。<br /></font>const #1 = Method #3.#12; //  java/lang/Object."&lt;init&gt;":()V<br /><font style="BACKGROUND-COLOR: #ff0000">因为Constant pool#0是不用的，所以只能从#1开始，但不知为什么第一个是Method而不是class，我现在还不明白。</font><br />const #2 = class #13; //  Act<br /><font style="BACKGROUND-COLOR: #ff0000">CONSTANT_Class是对一个类或接口的符号引用。这个是指向#13</font><br />const #3 = class #14; //  java/lang/Object<br />const #4 = Asciz &lt;init&gt;;<br /></font>
		<font size="2">
				<font style="BACKGROUND-COLOR: #ff0000"> 这个Asciz应该表示是CONSTANT_Utf8吧，因为C ONSTANT_Utf8可以是存储四种基本信息类型：文字字符串、被定义的类和接口描述、对其他类或接口的符号引用以及属性相关的字符串。<br />&lt;init&gt;是实例的初始化方法，是实例调用方法前必须要&lt;init&gt;的，<br />&lt;clinit&gt;是类的初始化方法。<br /></font>const #5 = Asciz ()V;<br /></font>
		<font size="2">
				<font style="BACKGROUND-COLOR: #ff0000">此&lt;init&gt;的描述符，()V表示&lt;init&gt;没有带参数，返回的是void型的。<br />书上介绍：<br />()I  int getSize()  <br />() Ljava/lang/String      String toString()</font>
				<br />const #6 = Asciz Code;<br /></font>
		<font size="2">
				<font style="BACKGROUND-COLOR: #ff0000">Code在所有不是抽象或者本地方法的method_info信息中,都存在一个Code_attribute表。<br />但是我试一下在抽象的方法中同样也有code的啊，不懂中。<br /></font>const #7 = Asciz LineNumberTable;<br /></font>
		<font size="2">
				<font style="BACKGROUND-COLOR: #ff0000">LineNumberTable属性建立了方法字节码流偏移量和源代码行号之间的映射关系。关于这一点，我在下面详细谈到。<br /></font>const #8 = Asciz doMathForever;<br /><font style="BACKGROUND-COLOR: #ffff66">#8 字段名和方法名以简单名称出现在常量池的入口中，存的时候存简单名字，调用的时候要加 上全限定名<br /></font>const #9 = Asciz (I)V;<br /><font style="BACKGROUND-COLOR: #ffff66">doMathForover的描述符，参数是int类型，返回值是void类型<br /></font>const #10 = Asciz SourceFile;<br />const #11 = Asciz Act.java;<br />const #12 = NameAndType #4:#5;//  "&lt;init&gt;":()V<br /></font>
		<font size="2">
				<font style="BACKGROUND-COLOR: #ff0000">NameAndType指向字段或者方法的符号引用的一部分。为什么没有指向#8,#9呢？不懂中。<br /></font>const #13 = Asciz Act;<br />const #14 = Asciz java/lang/Object; <br /></font>
		<p align="justify">
				<font size="2">
						<font style="BACKGROUND-COLOR: #ffff33">#13,#14 CONSTANT_Utf8_info 表的入口，容纳了 类/接口全限定名等信息。用“/”代替“.”。在class文件的this_class字段是对常量池的一个引用，指向了常量池中CONSTANT_ClASS_info表，该表由两项组成，即标签和name_index。在这个例子里，this_class的值为2，也就是常量池里的第二项，这项标签是class，name_index是13，即指向常量池的第13项。第13项里就有当前类的全限定名。</font>
						<br />{<br />Act();<br />  Code:<br />   Stack=1, Locals=1, Args_size=1<br /></font>
				<font size="2">
						<font style="BACKGROUND-COLOR: #ff0000">需要的栈为1个，只是this的存取;本地变量为1个，也是this,方法的参数是1个，也是this传入。<br /></font>   0: aload_0<br /><font style="BACKGROUND-COLOR: #ff0000">从局部变量0中装载引用类型。</font><br />   1: invokespecial #1; //Method java/lang/Object."&lt;init&gt;":()V<br /><font style="BACKGROUND-COLOR: #ff0000">调用Object的&lt;init&gt;方法，因为每个类都是继承Object，所以实例时都要调用Object的&lt;init&gt;方法。</font><br />   4: return<br />  LineNumberTable: <br />   line 1: 0</font>
		</p>
		<p align="justify">
				<font size="2">public static void doMathForever(int);<br />  Code:<br />   Stack=2, Locals=3, Args_size=1<br />   0: iconst_0 </font>
				<font size="2">
						<font style="BACKGROUND-COLOR: #ff0000">将i 压入栈<br /></font>   1: istore_1 </font>
				<font size="2">
						<font style="BACKGROUND-COLOR: #ff0000">放i<br /></font>   2: iconst_1 </font>
				<font size="2">
						<font style="BACKGROUND-COLOR: #ff0000">同上<br /></font>   3: istore_2<br />   4: iinc 1, 1  i++<br />  7   iload_1 <font style="BACKGROUND-COLOR: #ff0000">从局部变量1中装载int类型值。</font><br />   8: iconst_2<br />   9: imul<br />   10: istore_1<br />   11: goto 4<br />  LineNumberTable: <br />   line 3: 0  <font style="BACKGROUND-COLOR: #ff0000">源代码第3行对应Code中的0偏移量。</font><br />   line 4: 2<br />   line 6: 4<br />   line 7: 7<br />   line 8: 11</font>
		</p>
		<p align="justify">
				<font size="2">}<br /></font>
		</p>
<img src ="http://www.blogjava.net/baogenfly/aggbug/78557.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/baogenfly/" target="_blank">王某某</a> 2006-11-01 21:30 <a href="http://www.blogjava.net/baogenfly/articles/78557.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>