首页 > 代码库 > java class文件解析(一)

java class文件解析(一)

读取class文件,解析数据流。

package readClass;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import readClass.util.UtilMap;

/**
* 模拟虚拟机解析class文件
*
* @author Administrator
*
*/
public class MyPraseClassFile
{
static char[] xIndex ={‘0‘,‘1‘,‘2‘,‘3‘,‘4‘,‘5‘,‘6‘,‘7‘,‘8‘,‘9‘,‘A‘,‘B‘,‘C‘,‘D‘,‘E‘,‘F‘};
public static void main(String[] args)
{
Map<String,List> resultMap = new HashMap<String,List>(); //用来记录constants中的值
Map<String,ClassBean> tempMap = new HashMap<String,ClassBean>();
try
{
DataInputStream stream = new DataInputStream(MyPraseClassFile.class.getResourceAsStream("exampleClass/ExampleClass.class"));
byte[] b = new byte[4];
int index = 0;
stream.read(b);
ClassBean bean = null;
System.out.println("magic----->"+convert0x(b,index,4));
System.out.println("minor_version----->"+stream.readShort());
System.out.println("major_version----->"+stream.readShort());
int constantsCountt =stream.readShort();
System.out.println("constants_pool_count----->"+constantsCountt);

List list = null; //
for(int count =1;count<constantsCountt;count++) //遍历常量池
{
//读取常量类型
byte tempByte = stream.readByte();
list = resultMap.get(String.valueOf(tempByte));
if(null == list)
{
list = new ArrayList();
resultMap.put(String.valueOf(tempByte),list);
}
bean = new ClassBean();
tempMap.put(String.valueOf(count), bean); //用于之后的查找
list.add(bean);
bean.setIndex(count);
bean.setTag(tempByte);
switch (tempByte)
{
case 1: short length = stream.readShort(); b = new byte[length]; stream.read(b); bean.setValue(new String(b)); break;
case 3: bean.setValue(String.valueOf(stream.readInt())); break;
case 4: bean.setValue(String.valueOf(stream.readFloat())); break;
case 5: bean.setValue(String.valueOf(stream.readLong())); count++; break;
case 6: bean.setValue(String.valueOf(stream.readDouble())); count++; break;
case 7: bean.setRefUtf(stream.readShort()); break;
case 8: bean.setRefUtf(stream.readShort()); break;
case 9: bean.setRefClass(stream.readShort());bean.setRefTypeAndName(stream.readShort()); break;
case 10: bean.setRefClass(stream.readShort());bean.setRefTypeAndName(stream.readShort()); break;
case 11: bean.setRefClass(stream.readShort());bean.setRefTypeAndName(stream.readShort()); break;
case 12: bean.setRefClass(stream.readShort());bean.setRefUtf(stream.readShort()); break;
default: System.out.println("异常数据!") ;
}
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}

Iterator<String> it = resultMap.keySet().iterator();
while(it.hasNext())
{
String key = it.next();
System.out.println(UtilMap.getConstantMap().get(key)+"----->");
List list = resultMap.get(key);
for(int i = 0 ;i<list.size();i++)
{
ClassBean classBean =(ClassBean)list.get(i);
if(null != classBean.getValue())
{
System.out.println(classBean.getValue());
continue;
}
switch (classBean.getTag())
{
case 7: System.out.println(getUtfValue(tempMap,classBean.getRefUtf())); break;
case 8: System.out.println(getUtfValue(tempMap,classBean.getRefUtf()));break;
case 9: System.out.println(getClassValue(tempMap,classBean.getRefClass())+"||"+getRefTypeAndName(tempMap,classBean.getRefTypeAndName()));break;
case 10:System.out.println(getClassValue(tempMap,classBean.getRefClass())+"||"+getRefTypeAndName(tempMap,classBean.getRefTypeAndName()));break;
case 11:System.out.println(getClassValue(tempMap,classBean.getRefClass())+"||"+getRefTypeAndName(tempMap,classBean.getRefTypeAndName()));break;
}

}
}
}
/**
* 直接根据索引的值找对应的utf值
* @param tempMap
*/
private static String getUtfValue(Map<String,ClassBean> tempMap,int ref)
{
return tempMap.get(String.valueOf(ref)).getValue(); //指向utf值
}
/**
* 根据class索引找到class,再找对应的utf
* @return
*/
private static String getClassValue(Map<String,ClassBean> tempMap,int ref)
{
ClassBean bean = tempMap.get(String.valueOf(ref));
if(null != bean.getValue())
{
return bean.getValue();
}
String value = http://www.mamicode.com/tempMap.get(String.valueOf(bean.getRefUtf())).getValue();
bean.setValue(value);
return value;
}
/**
* 根据RefTypeAndName索引查找对应的value 同(class索引)
* @param tempMap
* @param ref
* @return
*/
private static String getRefTypeAndName(Map<String,ClassBean> tempMap,int ref)
{
ClassBean bean = tempMap.get(String.valueOf(ref));
if(null != bean.getValue())
{
return bean.getValue();
}
String value = http://www.mamicode.com/tempMap.get(String.valueOf(bean.getRefClass())).getValue();
bean.setValue(value);
return value;
}

/**
* 转换为16进制
* @param b
* @return
*/
private static String convert0x(byte[] b,int start,int length)
{
if(null == b || b.length ==0)
{
return null;
}
StringBuilder sql = new StringBuilder();
for(int i = start;i<start+length;i++)
{
byte temp = b[i];
sql.append(xIndex[(temp&0xF0)>>4]+""+xIndex[temp&0x0F]);
}
return sql.toString();
}
}

 

 

package readClass.util;

import java.util.HashMap;
import java.util.Map;

public class UtilMap
{
private static Map<String,String> constantMap = new HashMap<String,String>();
static
{
constantMap.put("1", "constant_utf-8");
constantMap.put("3", "constant_integer-info");
constantMap.put("4", "constant_float-info");
constantMap.put("5", "constant_double-info");
constantMap.put("6", "constant_Long-info");
constantMap.put("7", "constant_class-info");
constantMap.put("8", "constant_string-info");
constantMap.put("9", "constant_fieldRef-info");
constantMap.put("10", "constant_methodRef-info");
constantMap.put("11", "constant_interfaceRef-info");
constantMap.put("12", "constant_NameAndTypeRef-info");
}
public static Map<String, String> getConstantMap() {
return constantMap;
}
public static void setConstantMap(Map<String, String> constantMap) {
UtilMap.constantMap = constantMap;
}
}

 

package readClass;

public class ClassBean
{
private int index ;//当前所属开始索引(long,double比普通长)
private int tag; //1,3,4,5,6,7,8,9,10,11,12
private int refUtf; //指向具体的String
private int refClass; //指向的class索引
private int refTypeAndName;//指向的类型索引
private String value; //最终的值
public int getIndex()
{
return index;
}
public int getRefUtf() {
return refUtf;
}
public void setRefUtf(int refUtf) {
this.refUtf = refUtf;
}
public void setIndex(int index)
{
this.index = index;
}
public int getTag()
{
return tag;
}
public void setTag(int tag)
{
this.tag = tag;
}
public int getRefClass()
{
return refClass;
}
public void setRefClass(int refClass)
{
this.refClass = refClass;
}
public int getRefTypeAndName()
{
return refTypeAndName;
}
public void setRefTypeAndName(int refTypeAndName)
{
this.refTypeAndName = refTypeAndName;
}
public String getValue()
{
return value;
}
public void setValue(String value)
{
this.value = http://www.mamicode.com/value;
}
}

 

package readClass.exampleClass;
/**
*
* @author Administrator
*
*/
public class ExampleClass implements Comparable<Object>
{
private Long id;
private String name =new StringBuffer("22").toString();
private static Long staticId ;
private int k =0;
private Double AAA =0.23d;
private static final String CONSTANTS="constants";
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}


public Long getStaticId() {
return staticId;
}

public void setStaticId(Long staticId) {
this.staticId = staticId;
}

public Double getAAA() {
return AAA;
}

public void setAAA(Double aAA) {
AAA = aAA;
}

public static String getConstants() {
return CONSTANTS;
}

@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
return 0;
}
}

 

执行输出如下:

magic----->CAFEBABE
minor_version----->0
major_version----->50
constants_pool_count----->80
constant_methodRef-info----->
java/lang/Object||<init>
java/lang/StringBuffer||<init>
java/lang/StringBuffer||toString
java/lang/Double||valueOf
constant_utf-8----->
readClass/exampleClass/ExampleClass
java/lang/Object
java/lang/Comparable
id
Ljava/lang/Long;
name
Ljava/lang/String;
staticId
k
I
AAA
Ljava/lang/Double;
CONSTANTS
ConstantValue
constants
<init>
()V
Code
java/lang/StringBuffer
22
(Ljava/lang/String;)V
toString
()Ljava/lang/String;
java/lang/Double
valueOf
(D)Ljava/lang/Double;
LineNumberTable
LocalVariableTable
this
LreadClass/exampleClass/ExampleClass;
getId
()Ljava/lang/Long;
setId
(Ljava/lang/Long;)V
getName
setName
getStaticId
setStaticId
getAAA
()Ljava/lang/Double;
setAAA
(Ljava/lang/Double;)V
aAA
getConstants
compareTo
(Ljava/lang/Object;)I
o
Ljava/lang/Object;
SourceFile
ExampleClass.java
Signature
Ljava/lang/Object;Ljava/lang/Comparable<Ljava/lang/Object;>;
constant_class-info----->
readClass/exampleClass/ExampleClass
java/lang/Object
java/lang/Comparable
java/lang/StringBuffer
java/lang/Double
constant_Long-info----->
0.23
constant_fieldRef-info----->
readClass/exampleClass/ExampleClass||name
readClass/exampleClass/ExampleClass||k
readClass/exampleClass/ExampleClass||AAA
readClass/exampleClass/ExampleClass||id
readClass/exampleClass/ExampleClass||staticId
constant_string-info----->
constants
22
constant_NameAndTypeRef-info----->
<init>
<init>
toString
name
k
valueOf
AAA
id
staticId

java class文件解析(一)