src/org/nutz/lang/util/ClassTools.java
public static String getClassName(InputStream in) {
        try {
            DataInputStream dis = new DataInputStream(new BufferedInputStream(in));
            Map<Integer, String> strs = new HashMap<Integer, String>();
            Map<Integer, Integer> classes = new HashMap<Integer, Integer>();
            dis.skipBytes(4);//Magic
            dis.skipBytes(2);//副版本号
            dis.skipBytes(2);//主版本号
            
            //读取常量池
            int constant_pool_count = dis.readUnsignedShort();
            for (int i = 0; i < (constant_pool_count - 1); i++) {
                byte flag = dis.readByte();
                switch (flag) {
                case 7://CONSTANT_Class:
                    int index = dis.readUnsignedShort();
                    classes.put(i+1, index);
                    break;
                case 9://CONSTANT_Fieldref:
                case 10://CONSTANT_Methodref:
                case 11://CONSTANT_InterfaceMethodref:
                    dis.skipBytes(2);
                    dis.skipBytes(2);
                    break;
                case 8://CONSTANT_String:
                    dis.skipBytes(2);
                    break;
                case 3://CONSTANT_Integer:
                case 4://CONSTANT_Float:
                    dis.skipBytes(4);
                    break;
                case 5://CONSTANT_Long:
                case 6://CONSTANT_Double:
                    dis.skipBytes(8);
                    i++;//必须跳过一个,这是class文件设计的一个缺陷,历史遗留问题
                    break;
                case 12://CONSTANT_NameAndType:
                    dis.skipBytes(2);
                    dis.skipBytes(2);
                    break;
                case 1://CONSTANT_Utf8:
                    int len = dis.readUnsignedShort();
                    byte[] data = new byte[len];
                    dis.readFully(data);
                    strs.put(i + 1, new String(data, Encoding.UTF8));//必然是UTF8的
                    break;
                case 15://CONSTANT_MethodHandle:
                    dis.skipBytes(1);
                    dis.skipBytes(2);
                    break;
                case 16://CONSTANT_MethodType:
                    dis.skipBytes(2);
                    break;
                case 18://CONSTANT_InvokeDynamic:
                    dis.skipBytes(2);
                    dis.skipBytes(2);
                    break;
                default:
                    throw new RuntimeException("Impossible!! flag="+flag);
                }
            }
            
            dis.skipBytes(2);//版本控制符
            int pos = dis.readUnsignedShort();
            String name = strs.get(classes.get(pos));
            if (name != null)
                name = name.replace('/', '.');
            dis.close();
            return name;
        } catch (Throwable e) {
            if (log.isInfoEnabled()) 
                log.info("Fail to read ClassName from class InputStream", e);
        }
        return null;
    }
public static String getClassName(InputStream in) {
        try {
            DataInputStream dis = new DataInputStream(new BufferedInputStream(in));
            Map<Integer, String> strs = new HashMap<Integer, String>();
            Map<Integer, Integer> classes = new HashMap<Integer, Integer>();
            dis.skipBytes(4);//Magic
            dis.skipBytes(2);//副版本号
            dis.skipBytes(2);//主版本号
            
            //读取常量池
            int constant_pool_count = dis.readUnsignedShort();
            for (int i = 0; i < (constant_pool_count - 1); i++) {
                byte flag = dis.readByte();
                switch (flag) {
                case 7://CONSTANT_Class:
                    int index = dis.readUnsignedShort();
                    classes.put(i+1, index);
                    break;
                case 9://CONSTANT_Fieldref:
                case 10://CONSTANT_Methodref:
                case 11://CONSTANT_InterfaceMethodref:
                    dis.skipBytes(2);
                    dis.skipBytes(2);
                    break;
                case 8://CONSTANT_String:
                    dis.skipBytes(2);
                    break;
                case 3://CONSTANT_Integer:
                case 4://CONSTANT_Float:
                    dis.skipBytes(4);
                    break;
                case 5://CONSTANT_Long:
                case 6://CONSTANT_Double:
                    dis.skipBytes(8);
                    i++;//必须跳过一个,这是class文件设计的一个缺陷,历史遗留问题
                    break;
                case 12://CONSTANT_NameAndType:
                    dis.skipBytes(2);
                    dis.skipBytes(2);
                    break;
                case 1://CONSTANT_Utf8:
                    int len = dis.readUnsignedShort();
                    byte[] data = new byte[len];
                    dis.readFully(data);
                    strs.put(i + 1, new String(data, Encoding.UTF8));//必然是UTF8的
                    break;
                case 15://CONSTANT_MethodHandle:
                    dis.skipBytes(1);
                    dis.skipBytes(2);
                    break;
                case 16://CONSTANT_MethodType:
                    dis.skipBytes(2);
                    break;
                case 18://CONSTANT_InvokeDynamic:
                    dis.skipBytes(2);
                    dis.skipBytes(2);
                    break;
                default:
                    throw new RuntimeException("Impossible!! flag="+flag);
                }
            }
            
            dis.skipBytes(2);//版本控制符
            int pos = dis.readUnsignedShort();
            String name = strs.get(classes.get(pos));
            if (name != null)
                name = name.replace('/', '.');
            dis.close();
            return name;
        } catch (Throwable e) {
            if (log.isInfoEnabled()) 
                log.info("Fail to read ClassName from class InputStream", e);
        }
        return null;
    }
public static String getClassName ( InputStream in ) { try { DataInputStream dis = new DataInputStream ( new BufferedInputStream ( in ) ) ; Map < Integer , String > strs = new HashMap < Integer , String > ( ) ; Map < Integer , Integer > classes = new HashMap < Integer , Integer > ( ) ; dis . skipBytes ( 4 ) ; //Magic dis . skipBytes ( 2 ) ; //副版本号 dis . skipBytes ( 2 ) ; //主版本号 //读取常量池 int constant_pool_count = dis . readUnsignedShort ( ) ; for ( int i = 0 ; i < ( constant_pool_count - 1 ) ; i ++ ) { byte flag = dis . readByte ( ) ; switch ( flag ) { case 7 : //CONSTANT_Class: int index = dis . readUnsignedShort ( ) ; classes . put ( i + 1 , index ) ; break ; case 9 : //CONSTANT_Fieldref: case 10 : //CONSTANT_Methodref: case 11 : //CONSTANT_InterfaceMethodref: dis . skipBytes ( 2 ) ; dis . skipBytes ( 2 ) ; break ; case 8 : //CONSTANT_String: dis . skipBytes ( 2 ) ; break ; case 3 : //CONSTANT_Integer: case 4 : //CONSTANT_Float: dis . skipBytes ( 4 ) ; break ; case 5 : //CONSTANT_Long: case 6 : //CONSTANT_Double: dis . skipBytes ( 8 ) ; i ++ ; //必须跳过一个,这是class文件设计的一个缺陷,历史遗留问题 break ; case 12 : //CONSTANT_NameAndType: dis . skipBytes ( 2 ) ; dis . skipBytes ( 2 ) ; break ; case 1 : //CONSTANT_Utf8: int len = dis . readUnsignedShort ( ) ; byte [ ] data = new byte [ len ] ; dis . readFully ( data ) ; strs . put ( i + 1 , new String ( data , Encoding . UTF8 ) ) ; //必然是UTF8的 break ; case 15 : //CONSTANT_MethodHandle: dis . skipBytes ( 1 ) ; dis . skipBytes ( 2 ) ; break ; case 16 : //CONSTANT_MethodType: dis . skipBytes ( 2 ) ; break ; case 18 : //CONSTANT_InvokeDynamic: dis . skipBytes ( 2 ) ; dis . skipBytes ( 2 ) ; break ; default : throw new RuntimeException ( "Impossible!! flag=" + flag ) ; } } dis . skipBytes ( 2 ) ; //版本控制符 int pos = dis . readUnsignedShort ( ) ; String name = strs . get ( classes . get ( pos ) ) ; if ( name != null ) name = name . replace ( ' ' , ' ' ) ; dis . close ( ) ; return name ; } catch ( Throwable e ) { if ( log . isInfoEnabled ( ) ) log . info ( "Fail to read ClassName from class InputStream" , e ) ; } return null ; }
从输入流中读取Class的名字,输入流必须是Class文件格式
从输入流中读取Class的名字 输入流必须是Class文件格式