上文中,采用的是ClassFile来获取常量池信息,从而获得包名。
缺点是,依赖tools.jar包。
本文代码是将ClassFile解析代码抽取出来,进行简化,提升性能。
package org.hot2hot.utils; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang.StringUtils; /** * fast * @author jiaojianfeng * */ public class PackageFromClassFast { private final static int MAGIC = 0xCAFEBABE; public static String getPackage(String fileName) { DataInputStream in = null; try { in = new DataInputStream(new BufferedInputStream(new FileInputStream(fileName))); if (in.readInt() != MAGIC) { throw new IOException(fileName + "非Java class文件!"); } in.readUnsignedShort();// 次版本号 in.readUnsignedShort();// 主版本号 int i = in.readUnsignedShort();// 常量池长度 Map<Integer, Integer> classInfoMap = new HashMap<Integer, Integer>(); Map<Integer, String> classNameMap = new HashMap<Integer, String>(); //常量池 for (int j = 1; j < i; ++j) { int k = in.readUnsignedByte(); switch (k) { case 7: classInfoMap.put(j, in.readUnsignedShort()); break; case 6: in.readDouble(); ++j; break; case 9: in.readUnsignedShort(); in.readUnsignedShort(); break; case 4: in.readFloat(); break; case 3: in.readInt(); break; case 11: in.readUnsignedShort(); in.readUnsignedShort(); break; case 18: in.readUnsignedShort(); in.readUnsignedShort(); break; case 5: in.readLong(); ++j; break; case 15: in.readUnsignedByte(); in.readUnsignedShort(); break; case 16: in.readUnsignedShort(); break; case 10: in.readUnsignedShort(); in.readUnsignedShort(); break; case 12: in.readUnsignedShort(); in.readUnsignedShort(); break; case 8: in.readUnsignedShort(); break; case 1: classNameMap.put(j, in.readUTF()); break; case 2: case 13: case 14: case 17: default: throw new RuntimeException("class文件错误!"); } } //access flag in.readUnsignedShort(); //this class int thisClazz = in.readUnsignedShort(); return StringUtils.replace(classNameMap.get(classInfoMap.get(thisClazz)), "/", "."); } catch (IOException ioe) { ioe.printStackTrace(); } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } return null; } public static void main(String[] args) { System.out.println(getPackage("/Users/jiaojianfeng/Documents/empleyment/clazz/A.class")); } }
还是那句话,
如果有更简单的方法,望告知。