open jdk javap对于class文件的解析分析

来源:互联网 发布:中国人有钱知乎 编辑:程序博客网 时间:2024/05/22 16:40
package sun.tools.javap;import java.util.*;import java.io.*;/** * Central data repository of the Java Disassembler. * Stores all the information in java class file. * * @author  Sucheta Dambalkar (Adopted code from jdis) */public class ClassData implements RuntimeConstants {    private int magic;    private int minor_version;    private int major_version;    private int cpool_count;    private Object cpool[];    private int access;    private int this_class = 0;;    private int super_class;    private int interfaces_count;    private int[] interfaces = new int[0];;    private int fields_count;    private FieldData[] fields;    private int methods_count;    private MethodData[] methods;    private InnerClassData[] innerClasses;    private int attributes_count;    private AttrData[] attrs;    private String classname;    private String superclassname;    private int source_cpx=0;    private byte tags[];    private Hashtable indexHashAscii = new Hashtable();    private String pkgPrefix="";    private int pkgPrefixLen=0;    /**     * Read classfile to disassemble.     */    public ClassData(InputStream infile){        try{            this.read(new DataInputStream(infile));        }catch (FileNotFoundException ee) {            error("cant read file");        }catch (Error ee) {            ee.printStackTrace();            error("fatal error");        } catch (Exception ee) {            ee.printStackTrace();            error("fatal exception");        }    }    /**     * Reads and stores class file information.     */    public void read(DataInputStream in) throws IOException {        // Read the header        magic = in.readInt();//先读取魔法数,值为0xcafebabe,以此来区分是否为java class文件        if (magic != JAVA_MAGIC) {             throw new ClassFormatError("wrong magic: " +                                       toHex(magic) + ", expected " +                                       toHex(JAVA_MAGIC));        }        minor_version = in.readShort();        major_version = in.readShort();        if (major_version != JAVA_VERSION) {//class文件版本号,现在我的jdk版本里面配置的是45,JAVA_MINOR_VERSION为3        }        // Read the constant pool        readCP(in);//读取常量池        access = in.readUnsignedShort();//访问标识字段,标识是否为public,final,abstract等很多访问控制        this_class = in.readUnsignedShort();//类的常量池索引项        super_class = in.readUnsignedShort();//父类的常量池索引项        //Read interfaces.        interfaces_count = in.readUnsignedShort();//接口个数        if(interfaces_count > 0){            interfaces = new int[interfaces_count];        }        for (int i = 0; i < interfaces_count; i++) {            interfaces[i]=in.readShort();//每个接口的常量池索引项        }        // Read the fields        readFields(in);//读取类字段        // Read the methods        readMethods(in);//读取类的方法信息        // Read the attributes        attributes_count = in.readUnsignedShort(); //读取类的属性信息        attrs=new AttrData[attributes_count];        for (int k = 0; k < attributes_count; k++) {            int name_cpx=in.readUnsignedShort();            if (getTag(name_cpx)==CONSTANT_UTF8                && getString(name_cpx).equals("SourceFile")                ){      if (in.readInt()!=2)                    throw new ClassFormatError("invalid attr length");                source_cpx=in.readUnsignedShort();                AttrData attr=new AttrData(this);                attr.read(name_cpx);                attrs[k]=attr;            } else if (getTag(name_cpx)==CONSTANT_UTF8                       && getString(name_cpx).equals("InnerClasses")                       ){       int length=in.readInt();                       int num=in.readUnsignedShort();                       if (2+num*8 != length)                           throw new ClassFormatError("invalid attr length");                       innerClasses=new InnerClassData[num];                       for (int j = 0; j < num; j++) {                           InnerClassData innerClass=new InnerClassData(this);                           innerClass.read(in);                           innerClasses[j]=innerClass;                       }                       AttrData attr=new AttrData(this);                       attr.read(name_cpx);                       attrs[k]=attr;            } else {                AttrData attr=new AttrData(this);                attr.read(name_cpx, in);                attrs[k]=attr;            }        }        in.close();    } // end ClassData.read()    /**     * Reads and stores constant pool info.     */    void readCP(DataInputStream in) throws IOException {        cpool_count = in.readUnsignedShort();        tags = new byte[cpool_count];        cpool = new Object[cpool_count];        for (int i = 1; i < cpool_count; i++) {            byte tag = in.readByte();            switch(tags[i] = tag) {            case CONSTANT_UTF8:                String str=in.readUTF();                indexHashAscii.put(cpool[i] = str, new Integer(i));                break;            case CONSTANT_INTEGER:                cpool[i] = new Integer(in.readInt());                break;            case CONSTANT_FLOAT:                cpool[i] = new Float(in.readFloat());                break;            case CONSTANT_LONG:                cpool[i++] = new Long(in.readLong());                break;            case CONSTANT_DOUBLE:                cpool[i++] = new Double(in.readDouble());                break;            case CONSTANT_CLASS:            case CONSTANT_STRING:                cpool[i] = new CPX(in.readUnsignedShort());                break;            case CONSTANT_FIELD:            case CONSTANT_METHOD:            case CONSTANT_INTERFACEMETHOD:            case CONSTANT_NAMEANDTYPE:                cpool[i] = new CPX2(in.readUnsignedShort(), in.readUnsignedShort());                break;            case 0:            default:                throw new ClassFormatError("invalid constant type: " + (int)tags[i]);            }        }    }    /**     * Reads and strores field info.     */    protected void readFields(DataInputStream in) throws IOException {        int fields_count = in.readUnsignedShort();        fields=new FieldData[fields_count];        for (int k = 0; k < fields_count; k++) {            FieldData field=new FieldData(this);            field.read(in);            fields[k]=field;        }    }    /**     * Reads and strores Method info.     */    protected void readMethods(DataInputStream in) throws IOException {        int methods_count = in.readUnsignedShort();        methods=new MethodData[methods_count];        for (int k = 0; k < methods_count ; k++) {            MethodData method=new MethodData(this);            method.read(in);            methods[k]=method;        }    }    /**     * get a string     */    public String getString(int n) {        return (n == 0) ? null : (String)cpool[n];    }    /**     * get the type of constant given an index     */    public byte getTag(int n) {        try{            return tags[n];        } catch (ArrayIndexOutOfBoundsException e) {            return (byte)100;        }    }    static final String hexString="0123456789ABCDEF";    public static char hexTable[]=hexString.toCharArray();    static String toHex(long val, int width) {        StringBuffer s = new StringBuffer();        for (int i=width-1; i>=0; i--)            s.append(hexTable[((int)(val>>(4*i)))&0xF]);        return "0x"+s.toString();    }    static String toHex(long val) {        int width;        for (width=16; width>0; width--) {            if ((val>>(width-1)*4)!=0) break;        }        return toHex(val, width);    }    static String toHex(int val) {        int width;        for (width=8; width>0; width--) {            if ((val>>(width-1)*4)!=0) break;        }        return toHex(val, width);    }    public void error(String msg) {        System.err.println("ERROR:" +msg);    }    /**     * Returns the name of this class.     */    public String getClassName() {        String res=null;        if (this_class==0) {            return res;        }        int tcpx;        try {            if (tags[this_class]!=CONSTANT_CLASS) {                return res; //"<CP["+cpx+"] is not a Class> ";            }            tcpx=((CPX)cpool[this_class]).cpx;        } catch (ArrayIndexOutOfBoundsException e) {            return res; // "#"+cpx+"// invalid constant pool index";        } catch (Throwable e) {            return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";        }        try {            return (String)(cpool[tcpx]);        } catch (ArrayIndexOutOfBoundsException e) {            return  res; // "class #"+scpx+"// invalid constant pool index";        } catch (ClassCastException e) {            return  res; // "class #"+scpx+"// invalid constant pool reference";        } catch (Throwable e) {            return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";        }    }    /**     * Returns the name of class at perticular index.     */    public String getClassName(int cpx) {        String res="#"+cpx;        if (cpx==0) {            return res;        }        int scpx;        try {            if (tags[cpx]!=CONSTANT_CLASS) {                return res; //"<CP["+cpx+"] is not a Class> ";            }            scpx=((CPX)cpool[cpx]).cpx;        } catch (ArrayIndexOutOfBoundsException e) {            return res; // "#"+cpx+"// invalid constant pool index";        } catch (Throwable e) {            return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";        }        res="#"+scpx;        try {            return (String)(cpool[scpx]);        } catch (ArrayIndexOutOfBoundsException e) {            return  res; // "class #"+scpx+"// invalid constant pool index";        } catch (ClassCastException e) {            return  res; // "class #"+scpx+"// invalid constant pool reference";        } catch (Throwable e) {            return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";        }    }    /**     * Returns true if it is a class     */    public boolean isClass() {        if((access & ACC_INTERFACE) == 0) return true;        return false;    }    /**     * Returns true if it is a interface.     */    public boolean isInterface(){        if((access & ACC_INTERFACE) != 0) return true;        return false;    }    /**     * Returns true if this member is public, false otherwise.     */    public boolean isPublic(){        return (access & ACC_PUBLIC) != 0;    }    /**     * Returns the access of this class or interface.     */    public String[] getAccess(){        Vector v = new Vector();        if ((access & ACC_PUBLIC)   !=0) v.addElement("public");        if ((access & ACC_FINAL)    !=0) v.addElement("final");        if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract");        String[] accflags = new String[v.size()];        v.copyInto(accflags);        return accflags;    }    /**     * Returns list of innerclasses.     */    public InnerClassData[] getInnerClasses(){        return innerClasses;    }    /**     * Returns list of attributes.     */    public AttrData[] getAttributes(){        return attrs;    }    /**     * Returns true if superbit is set.     */    public boolean isSuperSet(){        if ((access & ACC_SUPER)   !=0) return true;        return false;    }    /**     * Returns super class name.     */    public String getSuperClassName(){        String res=null;        if (super_class==0) {            return res;        }        int scpx;        try {            if (tags[super_class]!=CONSTANT_CLASS) {                return res; //"<CP["+cpx+"] is not a Class> ";            }            scpx=((CPX)cpool[super_class]).cpx;        } catch (ArrayIndexOutOfBoundsException e) {            return res; // "#"+cpx+"// invalid constant pool index";        } catch (Throwable e) {            return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";        }        try {            return (String)(cpool[scpx]);        } catch (ArrayIndexOutOfBoundsException e) {            return  res; // "class #"+scpx+"// invalid constant pool index";        } catch (ClassCastException e) {            return  res; // "class #"+scpx+"// invalid constant pool reference";        } catch (Throwable e) {            return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";        }    }    /**     * Returns list of super interfaces.     */    public String[] getSuperInterfaces(){        String interfacenames[] = new String[interfaces.length];        int interfacecpx = -1;        for(int i = 0; i < interfaces.length; i++){            interfacecpx=((CPX)cpool[interfaces[i]]).cpx;            interfacenames[i] = (String)(cpool[interfacecpx]);        }        return interfacenames;    }    /**     * Returns string at prticular constant pool index.     */    public String getStringValue(int cpoolx) {        try {            return ((String)cpool[cpoolx]);        } catch (ArrayIndexOutOfBoundsException e) {            return "//invalid constant pool index:"+cpoolx;        } catch (ClassCastException e) {            return "//invalid constant pool ref:"+cpoolx;        }    }    /**     * Returns list of field info.     */    public  FieldData[] getFields(){        return fields;    }    /**     * Returns list of method info.     */    public  MethodData[] getMethods(){        return methods;    }    /**     * Returns constant pool entry at that index.     */    public CPX2 getCpoolEntry(int cpx){        return ((CPX2)(cpool[cpx]));    }    public Object getCpoolEntryobj(int cpx){        return (cpool[cpx]);    }    /**     * Returns index of this class.     */    public int getthis_cpx(){        return this_class;    }    public String TagString (int tag) {        String res=Tables.tagName(tag);        if (res==null)  return "BOGUS_TAG:"+tag;        return res;    }    /**     * Returns string at that index.     */    public String StringValue(int cpx) {        if (cpx==0) return "#0";        int tag;        Object x;        String suffix="";        try {            tag=tags[cpx];            x=cpool[cpx];        } catch (IndexOutOfBoundsException e) {            return "<Incorrect CP index:"+cpx+">";        }        if (x==null) return "<NULL>";        switch (tag) {        case CONSTANT_UTF8: {            StringBuffer sb=new StringBuffer();            String s=(String)x;            for (int k=0; k<s.length(); k++) {                char c=s.charAt(k);                switch (c) {                case '\t': sb.append('\\').append('t'); break;                case '\n': sb.append('\\').append('n'); break;                case '\r': sb.append('\\').append('r'); break;                case '\"': sb.append('\\').append('\"'); break;                default: sb.append(c);                }            }            return sb.toString();        }        case CONSTANT_DOUBLE: {            Double d=(Double)x;            String sd=d.toString();            return sd+"d";        }        case CONSTANT_FLOAT: {            Float f=(Float)x;            String sf=(f).toString();            return sf+"f";        }        case CONSTANT_LONG: {            Long ln = (Long)x;            return ln.toString()+'l';        }        case CONSTANT_INTEGER: {            Integer in = (Integer)x;            return in.toString();        }        case CONSTANT_CLASS:            return javaName(getClassName(cpx));        case CONSTANT_STRING:            return StringValue(((CPX)x).cpx);        case CONSTANT_FIELD:        case CONSTANT_METHOD:        case CONSTANT_INTERFACEMETHOD:            //return getShortClassName(((CPX2)x).cpx1)+"."+StringValue(((CPX2)x).cpx2);             return javaName(getClassName(((CPX2)x).cpx1))+"."+StringValue(((CPX2)x).cpx2);        case CONSTANT_NAMEANDTYPE:            return getName(((CPX2)x).cpx1)+":"+StringValue(((CPX2)x).cpx2);        default:            return "UnknownTag"; //TBD        }    }    /**     * Returns resolved java type name.     */    public String javaName(String name) {        if( name==null) return "null";        int len=name.length();        if (len==0) return "\"\"";        int cc='/';    fullname: { // xxx/yyy/zzz            int cp;            for (int k=0; k<len; k += Character.charCount(cp)) {                cp=name.codePointAt(k);                if (cc=='/') {                    if (!Character.isJavaIdentifierStart(cp)) break fullname;                } else if (cp!='/') {                    if (!Character.isJavaIdentifierPart(cp)) break fullname;                }                cc=cp;            }            return name;        }        return "\""+name+"\"";    }    public String getName(int cpx) {        String res;        try {            return javaName((String)cpool[cpx]); //.replace('/','.');        } catch (ArrayIndexOutOfBoundsException e) {            return "<invalid constant pool index:"+cpx+">";        } catch (ClassCastException e) {            return "<invalid constant pool ref:"+cpx+">";        }    }    /**     * Returns unqualified class name.     */    public String getShortClassName(int cpx) {        String classname=javaName(getClassName(cpx));        pkgPrefixLen=classname.lastIndexOf("/")+1;        if (pkgPrefixLen!=0) {            pkgPrefix=classname.substring(0,pkgPrefixLen);            if (classname.startsWith(pkgPrefix)) {                return classname.substring(pkgPrefixLen);            }        }        return classname;    }    /**     * Returns source file name.     */    public String getSourceName(){        return getName(source_cpx);    }    /**     * Returns package name.     */    public String getPkgName(){        String classname=getClassName(this_class);        pkgPrefixLen=classname.lastIndexOf("/")+1;        if (pkgPrefixLen!=0) {            pkgPrefix=classname.substring(0,pkgPrefixLen);            return("package  "+pkgPrefix.substring(0,pkgPrefixLen-1)+";\n");        }else return null;    }    /**     * Returns total constant pool entry count.     */    public int getCpoolCount(){        return cpool_count;    }    public String StringTag(int cpx) {        byte tag=0;        String str=null;        try {            if (cpx==0) throw new IndexOutOfBoundsException();            tag=tags[cpx];            return      TagString(tag);        } catch (IndexOutOfBoundsException e) {            str="Incorrect CP index:"+cpx;        }        return str;    }    /**     * Returns minor version of class file.     */    public int getMinor_version(){        return minor_version;    }    /**     * Returns major version of class file.     */    public int getMajor_version(){        return major_version;    }        public static void main(String[] args) throws FileNotFoundException{    System.out.println(new ClassData(new FileInputStream(new File("E:\\logs\\Example.class"))));    }}


读取类的field信息的类:
package sun.tools.javap;import java.util.*;import java.io.*;/** * Strores field data informastion. * * @author  Sucheta Dambalkar (Adopted code from jdis) */public class FieldData implements RuntimeConstants  {    ClassData cls;    int access;    int name_index;    int descriptor_index;    int attributes_count;    int value_cpx=0;    boolean isSynthetic=false;    boolean isDeprecated=false;    Vector attrs;    public FieldData(ClassData cls){        this.cls=cls;    }    /**     * Read and store field info.     */    public void read(DataInputStream in) throws IOException {        access = in.readUnsignedShort();        name_index = in.readUnsignedShort();        descriptor_index = in.readUnsignedShort();        // Read the attributes        int attributes_count = in.readUnsignedShort();        attrs=new Vector(attributes_count);        for (int i = 0; i < attributes_count; i++) {            int attr_name_index=in.readUnsignedShort();            if (cls.getTag(attr_name_index)!=CONSTANT_UTF8) continue;            String attr_name=cls.getString(attr_name_index);            if (attr_name.equals("ConstantValue")){                if (in.readInt()!=2)                    throw new ClassFormatError("invalid ConstantValue attr length");                value_cpx=in.readUnsignedShort();                AttrData attr=new AttrData(cls);                attr.read(attr_name_index);                attrs.addElement(attr);            } else if (attr_name.equals("Synthetic")){                if (in.readInt()!=0)                    throw new ClassFormatError("invalid Synthetic attr length");                isSynthetic=true;                AttrData attr=new AttrData(cls);                attr.read(attr_name_index);                attrs.addElement(attr);            } else if (attr_name.equals("Deprecated")){                if (in.readInt()!=0)                    throw new ClassFormatError("invalid Synthetic attr length");                isDeprecated = true;                AttrData attr=new AttrData(cls);                attr.read(attr_name_index);                attrs.addElement(attr);            } else {                AttrData attr=new AttrData(cls);                attr.read(attr_name_index, in);                attrs.addElement(attr);            }        }    }  // end read    /**     * Returns access of a field.     */    public String[] getAccess(){        Vector v = new Vector();        if ((access & ACC_PUBLIC)   !=0) v.addElement("public");        if ((access & ACC_PRIVATE)   !=0) v.addElement("private");        if ((access & ACC_PROTECTED)   !=0) v.addElement("protected");        if ((access & ACC_STATIC)   !=0) v.addElement("static");        if ((access & ACC_FINAL)    !=0) v.addElement("final");        if ((access & ACC_VOLATILE) !=0) v.addElement("volatile");        if ((access & ACC_TRANSIENT) !=0) v.addElement("transient");        String[] accflags = new String[v.size()];        v.copyInto(accflags);        return accflags;    }    /**     * Returns name of a field.     */    public String getName(){        return cls.getStringValue(name_index);    }    /**     * Returns internal signature of a field     */    public String getInternalSig(){        return cls.getStringValue(descriptor_index);    }    /**     * Returns java type signature of a field.     */    public String getType(){        return new TypeSignature(getInternalSig()).getFieldType();    }    /**     * Returns true if field is synthetic.     */    public boolean isSynthetic(){        return isSynthetic;    }    /**     * Returns true if field is deprecated.     */    public boolean isDeprecated(){        return isDeprecated;    }    /**     * Returns index of constant value in cpool.     */    public int getConstantValueIndex(){        return (value_cpx);    }    /**     * Returns list of attributes of field.     */    public Vector getAttributes(){        return attrs;    }}

读取类的方法

import java.util.*;import java.io.*;import static sun.tools.javap.RuntimeConstants.*;/** * Strores method data informastion. * * @author  Sucheta Dambalkar (Adopted code from jdis) */public class MethodData {    ClassData cls;    int access;    int name_index;    int descriptor_index;    int attributes_count;    byte[] code;    Vector exception_table = new Vector(0);    Vector lin_num_tb = new Vector(0);    Vector loc_var_tb = new Vector(0);    StackMapTableData[] stackMapTable;    StackMapData[] stackMap;    int[] exc_index_table=null;    Vector attrs=new Vector(0);    Vector code_attrs=new Vector(0);    int max_stack,  max_locals;    boolean isSynthetic=false;    boolean isDeprecated=false;    public MethodData(ClassData cls){        this.cls=cls;    }    /**     * Read method info.     */    public void read(DataInputStream in) throws IOException {        access = in.readUnsignedShort();        name_index=in.readUnsignedShort();        descriptor_index =in.readUnsignedShort();        int attributes_count = in.readUnsignedShort();        for (int i = 0; i < attributes_count; i++) {            int attr_name_index=in.readUnsignedShort();        readAttr: {                if (cls.getTag(attr_name_index)==CONSTANT_UTF8) {                    String  attr_name=cls.getString(attr_name_index);                    if ( attr_name.equals("Code")){                        readCode (in);                        AttrData attr=new AttrData(cls);                        attr.read(attr_name_index);                        attrs.addElement(attr);                        break readAttr;                    } else if ( attr_name.equals("Exceptions")){                        readExceptions(in);                        AttrData attr=new AttrData(cls);                        attr.read(attr_name_index);                        attrs.addElement(attr);                        break readAttr;                    } else if (attr_name.equals("Synthetic")){                        if (in.readInt()!=0)                            throw new ClassFormatError("invalid Synthetic attr length");                        isSynthetic=true;                        AttrData attr=new AttrData(cls);                        attr.read(attr_name_index);                        attrs.addElement(attr);                        break readAttr;                    } else if (attr_name.equals("Deprecated")){                        if (in.readInt()!=0)                            throw new ClassFormatError("invalid Synthetic attr length");                        isDeprecated = true;                        AttrData attr=new AttrData(cls);                        attr.read(attr_name_index);                        attrs.addElement(attr);                        break readAttr;                    }                }                AttrData attr=new AttrData(cls);                attr.read(attr_name_index, in);                attrs.addElement(attr);            }        }    }    /**     * Read code attribute info.     */    public void readCode(DataInputStream in) throws IOException {        int attr_length = in.readInt();        max_stack=in.readUnsignedShort();        max_locals=in.readUnsignedShort();        int codelen=in.readInt();        code=new byte[codelen];        int totalread = 0;        while(totalread < codelen){            totalread += in.read(code, totalread, codelen-totalread);        }        //      in.read(code, 0, codelen);        int clen = 0;        readExceptionTable(in);        int code_attributes_count = in.readUnsignedShort();        for (int k = 0 ; k < code_attributes_count ; k++) {            int table_name_index=in.readUnsignedShort();            int table_name_tag=cls.getTag(table_name_index);            AttrData attr=new AttrData(cls);            if (table_name_tag==CONSTANT_UTF8) {                String table_name_tstr=cls.getString(table_name_index);                if (table_name_tstr.equals("LineNumberTable")) {                    readLineNumTable(in);                    attr.read(table_name_index);                } else if (table_name_tstr.equals("LocalVariableTable")) {                    readLocVarTable(in);                    attr.read(table_name_index);                } else if (table_name_tstr.equals("StackMapTable")) {                    readStackMapTable(in);                    attr.read(table_name_index);                } else if (table_name_tstr.equals("StackMap")) {                    readStackMap(in);                    attr.read(table_name_index);                } else {                    attr.read(table_name_index, in);                }                code_attrs.addElement(attr);                continue;            }            attr.read(table_name_index, in);            code_attrs.addElement(attr);        }    }    /**     * Read exception table info.     */    void readExceptionTable (DataInputStream in) throws IOException {        int exception_table_len=in.readUnsignedShort();        exception_table=new Vector(exception_table_len);        for (int l = 0; l < exception_table_len; l++) {            exception_table.addElement(new TrapData(in, l));        }    }    /**     * Read LineNumberTable attribute info.     */    void readLineNumTable (DataInputStream in) throws IOException {        int attr_len = in.readInt(); // attr_length        int lin_num_tb_len = in.readUnsignedShort();        lin_num_tb=new Vector(lin_num_tb_len);        for (int l = 0; l < lin_num_tb_len; l++) {            lin_num_tb.addElement(new LineNumData(in));        }    }    /**     * Read LocalVariableTable attribute info.     */    void readLocVarTable (DataInputStream in) throws IOException {        int attr_len=in.readInt(); // attr_length        int loc_var_tb_len = in.readUnsignedShort();        loc_var_tb = new Vector(loc_var_tb_len);        for (int l = 0; l < loc_var_tb_len; l++) {            loc_var_tb.addElement(new LocVarData(in));        }    }    /**     * Read Exception attribute info.     */    public void readExceptions(DataInputStream in) throws IOException {        int attr_len=in.readInt(); // attr_length in prog        int num_exceptions = in.readUnsignedShort();        exc_index_table=new int[num_exceptions];        for (int l = 0; l < num_exceptions; l++) {            int exc=in.readShort();            exc_index_table[l]=exc;        }    }    /**     * Read StackMapTable attribute info.     */    void readStackMapTable(DataInputStream in) throws IOException {        int attr_len = in.readInt();  //attr_length        int stack_map_tb_len = in.readUnsignedShort();        stackMapTable = new StackMapTableData[stack_map_tb_len];        for (int i=0; i<stack_map_tb_len; i++) {            stackMapTable[i] = StackMapTableData.getInstance(in, this);        }    }    /**     * Read StackMap attribute info.     */    void readStackMap(DataInputStream in) throws IOException {        int attr_len = in.readInt();  //attr_length        int stack_map_len = in.readUnsignedShort();        stackMap = new StackMapData[stack_map_len];        for (int i = 0; i<stack_map_len; i++) {            stackMap[i] = new StackMapData(in, this);        }    }    /**     * Return access of the method.     */    public String[] getAccess(){        Vector v = new Vector();        if ((access & ACC_PUBLIC)   !=0) v.addElement("public");        if ((access & ACC_PRIVATE)   !=0) v.addElement("private");        if ((access & ACC_PROTECTED)   !=0) v.addElement("protected");        if ((access & ACC_STATIC)   !=0) v.addElement("static");        if ((access & ACC_FINAL)    !=0) v.addElement("final");        if ((access & ACC_SYNCHRONIZED) !=0) v.addElement("synchronized");        if ((access & ACC_NATIVE) !=0) v.addElement("native");        if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract");        if ((access & ACC_STRICT) !=0) v.addElement("strictfp");        String[] accflags = new String[v.size()];        v.copyInto(accflags);        return accflags;    }    /**     * Return name of the method.     */    public String getName(){        return cls.getStringValue(name_index);    }    /**     * Return internal siganature of the method.     */    public String getInternalSig(){        return cls.getStringValue(descriptor_index);    }    /**     * Return java return type signature of method.     */    public String getReturnType(){        String rttype = (new TypeSignature(getInternalSig())).getReturnType();        return rttype;    }    /**     * Return java type parameter signature.     */    public String getParameters(){        String ptype = (new TypeSignature(getInternalSig())).getParameters();        return ptype;    }    /**     * Return code attribute data of a method.     */    public byte[] getCode(){        return code;    }    /**     * Return LineNumberTable size.     */    public int getnumlines(){        return lin_num_tb.size();    }    /**     * Return LineNumberTable     */    public Vector getlin_num_tb(){        return lin_num_tb;    }    /**     * Return LocalVariableTable size.     */    public int getloc_var_tbsize(){        return loc_var_tb.size();    }    /**     * Return LocalVariableTable.     */    public Vector getloc_var_tb(){        return loc_var_tb;    }    /**     * Return StackMap.     */    public StackMapData[] getStackMap() {        return stackMap;    }    /**     * Return StackMapTable.     */    public StackMapTableData[] getStackMapTable() {        return stackMapTable;    }    /**     * Return number of arguments of that method.     */    public int getArgumentlength(){        return new TypeSignature(getInternalSig()).getArgumentlength();    }    /**     * Return true if method is static     */    public boolean isStatic(){        if ((access & ACC_STATIC)   !=0) return true;        return false;    }    /**     * Return max depth of operand stack.     */    public int getMaxStack(){        return  max_stack;    }    /**     * Return number of local variables.     */    public int getMaxLocals(){        return max_locals;    }    /**     * Return exception index table in Exception attribute.     */    public int []get_exc_index_table(){        return  exc_index_table;    }    /**     * Return exception table in code attributre.     */    public Vector getexception_table(){        return exception_table;    }    /**     * Return method attributes.     */    public Vector getAttributes(){        return attrs;    }    /**     * Return code attributes.     */    public Vector getCodeAttributes(){        return code_attrs;    }    /**     * Return true if method id synthetic.     */    public boolean isSynthetic(){        return isSynthetic;    }    /**     * Return true if method is deprecated.     */    public boolean isDeprecated(){        return isDeprecated;    }}

我们将下面这个class文件解析之后的数据如下:过程很简单,有兴趣的大家调试一遍就知道了。

import java.io.PrintStream;public class AsmAopExample$Foo{  public static void execute()  {    AsmAopExample.Monitor.start(); System.out.println("test changed method name");    try {      Thread.sleep(10L);    }    catch (InterruptedException e) {      e.printStackTrace();    }    AsmAopExample.Monitor.end();  }}




 


原创粉丝点击