📄 classfile.java
字号:
* @throws InvalidByteCodeException if the entry is invalid
*/
public String getConstantPoolEntryName(int index)
throws InvalidByteCodeException {
if (!checkValidConstantPoolIndex(index)) {
return null;
}
CPInfo cpInfo = constantPool[index];
if (cpInfo == null) {
return "invalid constant pool index";
} else {
return cpInfo.getVerbose();
}
}
/**
* Get the index of a field for given field name and signature.
*
* @param name the field name.
* @param descriptor the signature.
* @return the index or <tt>-1</tt> if not found.
* @throws InvalidByteCodeException
*/
public int getFieldIndex(String name, String descriptor) throws InvalidByteCodeException {
for (int i = 0; i < fields.length; i++) {
FieldInfo field = fields[i];
if (field.getName().equals(name) && field.getDescriptor().equals(descriptor)) {
return i;
}
}
return -1;
}
/**
* Get the <tt>FieldInfo</tt> for given field name and signature.
*
* @param name the field name.
* @param descriptor the signature.
* @return the <tt>FieldInfo</tt> or <tt>null</tt> if not found.
* @throws InvalidByteCodeException
*/
public FieldInfo getField(String name, String descriptor) throws InvalidByteCodeException {
int index = getFieldIndex(name, descriptor);
if (index < 0) {
return null;
} else {
return fields[index];
}
}
/**
* Get the index of a method for given method name and signature.
*
* @param name the method name.
* @param descriptor the signature.
* @return the index or <tt>-1</tt> if not found.
* @throws InvalidByteCodeException
*/
public int getMethodIndex(String name, String descriptor) throws InvalidByteCodeException {
for (int i = 0; i < methods.length; i++) {
MethodInfo method = methods[i];
if (method.getName().equals(name) && method.getDescriptor().equals(descriptor)) {
return i;
}
}
return -1;
}
/**
* Get the <tt>MethodInfo</tt> for given method name and signature.
*
* @param name the method name.
* @param descriptor the signature.
* @return the <tt>MethodInfo</tt> or <tt>null</tt> if not found.
* @throws InvalidByteCodeException
*/
public MethodInfo getMethod(String name, String descriptor) throws InvalidByteCodeException {
int index = getMethodIndex(name, descriptor);
if (index < 0) {
return null;
} else {
return methods[index];
}
}
public void read(DataInput in)
throws InvalidByteCodeException, IOException {
readMagicNumber(in);
readVersion(in);
readConstantPool(in);
readAccessFlags(in);
readThisClass(in);
readSuperClass(in);
readInterfaces(in);
readFields(in);
readMethods(in);
readAttributes(in);
}
public void write(DataOutput in)
throws InvalidByteCodeException, IOException {
writeMagicNumber(in);
writeVersion(in);
writeConstantPool(in);
writeAccessFlags(in);
writeThisClass(in);
writeSuperClass(in);
writeInterfaces(in);
writeFields(in);
writeMethods(in);
writeAttributes(in);
}
private boolean checkValidConstantPoolIndex(int index) {
if (index < 1 || index >= constantPool.length) {
return false;
}
return true;
}
private void readMagicNumber(DataInput in)
throws InvalidByteCodeException, IOException {
int magicNumber = in.readInt();
if (magicNumber != MAGIC_NUMBER) {
throw new InvalidByteCodeException("Invalid magic number 0x" +
Integer.toHexString(magicNumber) +
" instead of 0x" +
Integer.toHexString(MAGIC_NUMBER));
}
if (debug) debug("read magic number");
}
private void writeMagicNumber(DataOutput out) throws IOException {
out.writeInt(MAGIC_NUMBER);
if (debug) debug("wrote magic number");
}
private void readVersion(DataInput in) throws IOException {
minorVersion = in.readUnsignedShort();
if (debug) debug("read minor version " + minorVersion);
majorVersion = in.readUnsignedShort();
if (debug) debug("read major version " + majorVersion);
checkMajorVersion(majorVersion);
}
private void writeVersion(DataOutput out) throws IOException {
out.writeShort(minorVersion);
if (debug) debug("wrote minor version " + minorVersion);
out.writeShort(majorVersion);
if (debug) debug("wrote major version " + majorVersion);
checkMajorVersion(majorVersion);
}
private void readConstantPool(DataInput in)
throws InvalidByteCodeException, IOException {
constantPoolEntryToIndex.clear();
int constantPoolCount = in.readUnsignedShort();
if (debug) debug("read constant pool count " + constantPoolCount);
constantPool = new CPInfo[constantPoolCount];
// constantPool has effective length constantPoolCount - 1
// constantPool[0] defaults to null
for (int i = 1; i < constantPoolCount; i++) {
if (skipConstantPool) {
// see below for i++
i += CPInfo.skip(in);
} else {
// create CPInfos via factory method since the actual type
// of the constant is not yet known
if (debug) debug("reading constant pool entry " + i);
constantPool[i] = CPInfo.create(in, this);
constantPoolEntryToIndex.put(constantPool[i], new Integer(i));
if (constantPool[i] instanceof ConstantLargeNumeric) {
// CONSTANT_Double_info and CONSTANT_Long_info take 2 constant
// pool entries, the second entry is unusable (design mistake)
i++;
}
}
}
}
private void writeConstantPool(DataOutput out)
throws InvalidByteCodeException, IOException {
int lastFreeIndex;
for (lastFreeIndex = getLength(constantPool) - 1;
lastFreeIndex >= 0 && constantPool[lastFreeIndex] == null;
lastFreeIndex--) {
}
out.writeShort(lastFreeIndex + 1);
if (debug) debug("wrote constant pool count " + (lastFreeIndex + 1));
// constantPool[0] defaults to null and is not written into the class file
for (int i = 1; i <= lastFreeIndex; i++) {
if (constantPool[i] == null) {
throw new InvalidByteCodeException("constant pool entry " + i + " is null");
}
if (debug) debug("writing constant pool entry " + i);
constantPool[i].write(out);
if (constantPool[i] instanceof ConstantLargeNumeric) {
// CONSTANT_Double_info and CONSTANT_Long_info take 2 constant
// pool entries, the second entry is unusable (design mistake)
i++;
}
}
}
private void readAccessFlags(DataInput in) throws IOException {
accessFlags = in.readUnsignedShort();
if (debug) debug("read access flags " + printAccessFlags(accessFlags));
}
private void writeAccessFlags(DataOutput out) throws IOException {
out.writeShort(accessFlags);
if (debug) debug("wrote access flags " + printAccessFlags(accessFlags));
}
private void readThisClass(DataInput in) throws IOException {
thisClass = in.readUnsignedShort();
if (debug) debug("read this_class index " + thisClass);
}
private void writeThisClass(DataOutput out) throws IOException {
out.writeShort(thisClass);
if (debug) debug("wrote this_class index " + thisClass);
}
private void readSuperClass(DataInput in) throws IOException {
superClass = in.readUnsignedShort();
if (debug) debug("read super_class index " + superClass);
}
private void writeSuperClass(DataOutput out) throws IOException {
out.writeShort(superClass);
if (debug) debug("wrote super_class index " + superClass);
}
private void readInterfaces(DataInput in) throws IOException {
int interfacesCount = in.readUnsignedShort();
if (debug) debug("read interfaces count " + interfacesCount);
interfaces = new int[interfacesCount];
for (int i = 0; i < interfacesCount; i++) {
interfaces[i] = in.readUnsignedShort();
if (debug) debug("read interface index " + interfaces[i]);
}
}
private void writeInterfaces(DataOutput out) throws IOException {
int interfacesCount = getLength(interfaces);
out.writeShort(interfacesCount);
if (debug) debug("wrote interfaces count " + interfacesCount);
for (int i = 0; i < interfacesCount; i++) {
out.writeShort(interfaces[i]);
if (debug) debug("wrote interface index " + interfaces[i]);
}
}
private void readFields(DataInput in)
throws InvalidByteCodeException, IOException {
int fieldsCount = in.readUnsignedShort();
if (debug) debug("read fields count " + fieldsCount);
fields = new FieldInfo[fieldsCount];
for (int i = 0; i < fieldsCount; i++) {
fields[i] = FieldInfo.create(in, this);
}
}
private void writeFields(DataOutput out)
throws InvalidByteCodeException, IOException {
int fieldsCount = getLength(fields);
out.writeShort(fieldsCount);
if (debug) debug("wrote fields count " + fieldsCount);
for (int i = 0; i < fieldsCount; i++) {
if (fields[i] == null) {
throw new InvalidByteCodeException("field " + i + " is null");
}
fields[i].write(out);
}
}
private void readMethods(DataInput in)
throws InvalidByteCodeException, IOException {
int methodsCount = in.readUnsignedShort();
if (debug) debug("read methods count " + methodsCount);
methods = new MethodInfo[methodsCount];
for (int i = 0; i < methodsCount; i++) {
methods[i] = MethodInfo.create(in, this);
}
}
private void writeMethods(DataOutput out)
throws InvalidByteCodeException, IOException {
int methodsCount = getLength(methods);
out.writeShort(methodsCount);
if (debug) debug("wrote methods count " + methodsCount);
for (int i = 0; i < methodsCount; i++) {
if (methods[i] == null) {
throw new InvalidByteCodeException("method " + i + " is null");
}
methods[i].write(out);
}
}
protected void readAttributes(DataInput in)
throws InvalidByteCodeException, IOException {
super.readAttributes(in);
if (debug) debug("read " + getLength(attributes) + " attributes for the ClassFile structure");
}
protected void writeAttributes(DataOutput out)
throws InvalidByteCodeException, IOException {
super.writeAttributes(out);
if (debug) debug("wrote " + getLength(attributes) + " attributes for the ClassFile structure");
}
private void checkMajorVersion(int majorVersion) {
if (majorVersion < 45 || majorVersion > 49) {
Log.warning("major version should be between 45 and 49 for JDK <= 1.5");
}
}
protected String printAccessFlagsVerbose(int accessFlags) {
return printAccessFlagsVerbose(AccessFlags.CLASS_ACCESS_FLAGS, AccessFlags.CLASS_ACCESS_FLAGS_VERBOSE, accessFlags);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -