在Org.SpringFrameWork.ASM这个包里面,有个类ClassReader,有个方法readclass ,后者主要功能是把流转换成16进制的Byte
代码如下:
private static byte[] readClass(final InputStream is, boolean close)
throws IOException {
if (is == null) {
throw new IOException("Class not found");
}
try {
byte[] b = new byte[is.available()];
int len = 0;
while (true) {
int n = is.read(b, len, b.length - len);
if (n == -1) {
if (len < b.length) {
byte[] c = new byte[len];
System.arraycopy(b, 0, c, 0, len);
b = c;
}
return b;
}
len += n;
if (len == b.length) {
int last = is.read();
if (last < 0) {
return b;
}
byte[] c = new byte[b.length + 1000];
System.arraycopy(b, 0, c, 0, len);
c[len++] = (byte) last;
b = c;
}
}
} finally {
if (close) {
is.close();
}
}
}
ClassReader 类在实例化new的时候,会获取到这个16进制byte里面的内容提取出类的头部和常量池里面最长的Utf-8字符串结构的Length .
代码如下:
public ClassReader(final byte[] b, final int off, final int len) {
this.b = b;
// checks the class version
/* SPRING PATCH: REMOVED FOR FORWARD COMPATIBILITY WITH JDK 9
if (readShort(off + 6) > Opcodes.V1_8) {
throw new IllegalArgumentException();
}
*/
// parses the constant pool
items = new int[readUnsignedShort(off + 8)];
int n = items.length;
strings = new String[n];
int max = 0;
int index = off + 10;
for (int i = 1; i < n; ++i) {
items[i] = index + 1;
int size;
switch (b[index]) {
case ClassWriter.FIELD:
case ClassWriter.METH:
case ClassWriter.IMETH:
case ClassWriter.INT:
case ClassWriter.FLOAT:
case ClassWriter.NAME_TYPE:
case ClassWriter.INDY:
size = 5;
break;
case ClassWriter.LONG:
case ClassWriter.DOUBLE:
size = 9;
++i;
break;
case ClassWriter.UTF8:
size = 3 + readUnsignedShort(index + 1);
if (size > max) {
max = size;
}
break;
case ClassWriter.HANDLE:
size = 4;
break;
// case ClassWriter.CLASS:
// case ClassWriter.STR:
// case ClassWriter.MTYPE
// case ClassWriter.PACKAGE:
// case ClassWriter.MODULE:
default:
size = 3;
break;
}
index += size;
}
maxStringLength = max;
// the class header information starts just after the constant pool
header = index;
}