`

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

    博客分类:
  • java
 
阅读更多

 

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();
  }
}

 




 

  • 大小: 105.3 KB
  • 大小: 115.2 KB
  • 大小: 81 KB
0
4
分享到:
评论

相关推荐

    [学习笔记]jdk1.7_class文件结构分析

    jdk1.7_class文件结构分析,常量池分析;jdk1.7_class文件结构分析,常量池分析;

    class识别jdk版本

    class识别jdk版本 jdk版本 class识别jdk版本 jdk版本

    jdk1.8class反编译

    在 JDK 1.8 版本中,开发者们有时需要查看已编译的`.class`文件的源代码,以便理解其内部工作原理或进行调试。这时,就需要用到反编译工具。反编译是从已编译的字节码文件(.class文件)还原出类似源代码的形式,...

    java class文件解析

    总的来说,Java Class文件解析是深入理解JVM工作原理和Java程序运行机制的关键,它不仅涉及到编程实践,也是软件调试、性能优化和安全分析的重要手段。通过学习这一领域的知识,开发者能够更好地驾驭Java平台,提升...

    OPEN jdk 11 windows 版本

    OPEN jdk 11 windows 版本

    class文件解析

    jad是一个早期的Java反汇编器,它可以解析Class文件并展示其中的字节码,但现代的开发环境中更常用的是javap,它是JDK自带的命令行工具,提供了丰富的选项来查看类的结构和字节码细节。 通过解码Class文件,开发者...

    输出JDK和CGLib动态代理产生的class文件.zip

    通过分析这些class文件,我们可以更深入地理解Java虚拟机(JVM)是如何执行动态代理的。同时,这两个项目也为我们提供了一个实践和调试动态代理的平台,有助于提升我们的编程技能和对Java底层机制的理解。

    class文件编译器.zip

    Javac是Java开发工具包(JDK)的一部分,它的主要任务是将`.java`源文件转换为`.class`文件。编译过程会检查源代码的语法和类型,确保符合Java语言规范,并生成对应的字节码。 3. **编译过程**: 当运行`javac ...

    JDK8/jdk1.8压缩版文件下载(压缩包)(无积分免费下载)

    1. **COPYRIGHT**: 这个文件通常包含Oracle公司对于JDK的版权信息,包括软件的许可条款和法律声明,确保用户在合法范围内使用软件。 2. **README.html**: 这是JDK的使用指南,通常会提供安装步骤、配置环境变量的...

    CentOS 安装配置JDK与Tomcat支持jsp文件解析

    1. 备份和编辑`server.xml`配置文件:将`/usr/local/tomcat/conf/server.xml`备份,并修改配置以支持.jsp文件解析,例如更改端口号和设置网站根目录。 2. 创建网站目录:根据修改后的配置,创建对应的网站目录,并...

    open-jdk-11-64位.zip

    "open-jdk-11-64位.zip"是一个包含64位架构的OpenJDK 11安装文件的压缩包,适用于64位操作系统。 1. **OpenJDK**:OpenJDK是一个自由、开源的Java SE平台实现,由全球开发者社区维护。它是Java Community Process...

    基于jdk1.6的傻瓜xml解析

    只要针对xml文件定义一个javaBean类,传入类的class对象,就可以通过本工具自动返回带有数据的bean类的实例。定义类的类名必要是标签名,类的属性对应标签的属性。本工具可以实现嵌套标签的解析,对应的bean定义规则...

    javaclass和源码-deep-in-jvm:简单的借助jdk中的内置工具帮助我们对比Java源码和生成的字节码以及探究Class文件字节

    java class和源码 deep-in-jvm ...运行javap分析Class文件字节码 javap -verbose Main &gt; Main.bytecode 分析包含内部类的源码编译出的Class文件 javap -verbose 'Main$Box.class' &gt; 'Main$Box.bytecode'

    JDK1.4工程下json解析包集合(内含6个jar包).zip

    此库对于老版本JDK的JSON解析至关重要。 5. **ezmorph-1.0.6.jar**:Ezmorph库提供了对象转换功能,使得在不同数据类型之间进行转换变得更加容易。在处理JSON数据时,可能会用到它来转换JSON中的值。 6. **commons...

    Open JDK有3种实现的compact JRE,数字越大,功能越丰富.docx

    Java开发的多样性与Open JDK的不同实现 Java作为一个广泛使用的编程语言,其应用范围远远超出了我们常见的移动端和服务端开发。Sun公司(后被Oracle收购)根据不同的业务领域划分了四个主要的Java Development Kit ...

    linux jdk1.7 安装 步骤完全解析

    - **版本管理**:对于多版本的JDK,可以使用`update-alternatives`工具来管理默认版本。 - **系统级配置**:如果你希望所有用户都能使用JDK,可以在 `/etc/profile` 或 `/etc/environment` 中设置环境变量,而不是在...

    无法解析类型 java.util.Map$Entry。从必需的 .class 文件间接引用了它

    这是我在编写struts2中遇到的问题,整理出来,包括截图,希望可以帮到大家

    Java开发环境JDK文件

    5. **开发工具**:如javadoc(生成API文档)、jar(打包和管理类文件)、jmap(内存映射工具)、jconsole(监控Java应用)、jvisualvm(多合一的Java性能分析工具)等。 安装JDK后,你需要配置环境变量,主要是`...

    profile(linux配置jdk环境所需文件)

    linux配置jdk环境变量的文件。

    jdk1.8.exe文件运行安装

    在本文中,我们将深入探讨如何下载和安装JDK 1.8的执行文件`jdk1.8.exe`。 首先,下载`jdk1.8.exe`文件是安装JDK 1.8的第一步。通常,你可以从Oracle官方网站获取最新的Java SE Development Kit 1.8版本。在Oracle...

Global site tag (gtag.js) - Google Analytics