⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classfile.java

📁 Java Bytecode Editor 是一个 JAVA 的字节码反汇编和修改器。它可以很方便的修改已经编译成 Class 文件的 JAVA 文件。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public
    License as published by the Free Software Foundation; either
    version 2 of the license, or (at your option) any later version.
*/

package org.gjt.jclasslib.structures;

import org.gjt.jclasslib.io.Log;
import org.gjt.jclasslib.structures.constants.ConstantLargeNumeric;
import org.gjt.jclasslib.structures.constants.ConstantUtf8Info;

import java.io.*;
import java.util.HashMap;

/**
 * The class file structure in which all other structures are hooked up.
 *
 * @author <a href="mailto:jclasslib@ej-technologies.com">Ingo Kegel</a>, <a href="mailto:vitor.carreira@gmail.com">Vitor Carreira</a>
 * @version $Revision: 1.3 $ $Date: 2006/09/04 15:43:18 $
 */
public class ClassFile extends AbstractStructureWithAttributes {

    /**
     * Set this JVM System property to true to skip reading of constant pool
     * entries. This is not advisable, since most sunsequent operations on the
     * class file structure will fail.
     */
    public static final String SYSTEM_PROPERTY_SKIP_CONSTANT_POOL = "jclasslib.io.skipConstantPool";

    private static final int MAGIC_NUMBER = 0xcafebabe;

    private final boolean skipConstantPool;

    private int minorVersion;
    private int majorVersion;
    private CPInfo[] constantPool;
    private HashMap<CPInfo, Integer> constantPoolEntryToIndex = new HashMap<CPInfo, Integer>();
    private int accessFlags;
    private int thisClass;
    private int superClass;
    private int[] interfaces;
    private FieldInfo[] fields;
    private MethodInfo[] methods;


    /**
     * Constructor.
     */
    public ClassFile() {
        skipConstantPool = Boolean.getBoolean(SYSTEM_PROPERTY_SKIP_CONSTANT_POOL);
        setClassFile(this);
    }

    /**
     * Get the minor version of the class file format.
     *
     * @return the minor version
     */
    public int getMinorVersion() {
        return minorVersion;
    }

    /**
     * Set the minor version of the class file format.
     *
     * @param minorVersion the minor version
     */
    public void setMinorVersion(int minorVersion) {
        this.minorVersion = minorVersion;
    }

    /**
     * Get the major version of the class file format.
     *
     * @return the major version
     */
    public int getMajorVersion() {
        return majorVersion;
    }

    /**
     * Set the major version of the class file format.
     *
     * @param majorVersion the major version
     */
    public void setMajorVersion(int majorVersion) {
        this.majorVersion = majorVersion;
    }

    /**
     * Get the array with all constant pool entries.
     *
     * @return the array
     */
    public CPInfo[] getConstantPool() {
        return constantPool;
    }

    /**
     * Get the index of an equivalent constant pool entry.
     *
     * @param cpInfo the constant pool entry
     * @return the index, -1 if no equivalent constant pool entry can be found
     */
    public int getConstantPoolIndex(CPInfo cpInfo) {
        Integer index = (Integer)constantPoolEntryToIndex.get(cpInfo);
        if (index != null) {
            return index.intValue();
        } else {
            return -1;
        }
    }

    /**
     * Set the array with all constant pool entries. An internal hash map
     * will need to be recalulated. If you add to the end of the constant
     * pool, use <tt>enlargeConstantPool</tt>.
     *
     * @param constantPool the array
     */
    public void setConstantPool(CPInfo[] constantPool) {
        this.constantPool = constantPool;
        for (int i = 0; i < constantPool.length; i++) {
            constantPoolEntryToIndex.put(constantPool[i], new Integer(i));
        }
    }

    /**
     * Set the array with all constant pool entries where the new array
     * of constant pool entries starts with the old constant pool. If
     * you delete entries, use <tt>setConstantPool</tt>.
     *
     * @param enlargedConstantPool the array
     */
    public void enlargeConstantPool(CPInfo[] enlargedConstantPool) {
        int startIndex = constantPool == null ? 0 : constantPool.length;
        this.constantPool = enlargedConstantPool;
        for (int i = startIndex; i < constantPool.length; i++) {
            if (constantPool[i] != null) {
                constantPoolEntryToIndex.put(constantPool[i], new Integer(i));
            }
        }
    }

    /**
     * Register the constant pool entry at a given index, so that it can
     * be found through the <tt>getConstantPoolIndex</tt> method.
     *
     * @param index the index
     */
    public void registerConstantPoolEntry(int index) {
        constantPoolEntryToIndex.put(constantPool[index], new Integer(index));
    }

    /**
     * Unregister the constant pool entry at a given index, so that it can
     * no longer be found through the <tt>getConstantPoolIndex</tt> method.
     *
     * @param index the index
     */
    public void unregisterConstantPoolEntry(int index) {
        constantPoolEntryToIndex.remove(constantPool[index]);
    }

    /**
     * Get the access flags of this class.
     *
     * @return the access flags
     */
    public int getAccessFlags() {
        return accessFlags;
    }

    /**
     * Set the access flags of this class.
     *
     * @param accessFlags the access flags
     */
    public void setAccessFlags(int accessFlags) {
        this.accessFlags = accessFlags;
    }

    /**
     * Get the constant pool index of this class.
     *
     * @return the index
     */
    public int getThisClass() {
        return thisClass;
    }

    /**
     * Set the constant pool index of this class.
     *
     * @param thisClass the index
     */
    public void setThisClass(int thisClass) {
        this.thisClass = thisClass;
    }

    /**
     * Get the name of this class.
     *
     * @return the name
     * @throws InvalidByteCodeException
     */
    public String getThisClassName() throws InvalidByteCodeException {
        return getConstantPoolEntryName(getThisClass());
    }

    /**
     * Get the constant pool index of the super class of this class.
     *
     * @return the index
     */
    public int getSuperClass() {
        return superClass;
    }

    /**
     * Set the constant pool index of the super class of this class.
     *
     * @param superClass the index
     */
    public void setSuperClass(int superClass) {
        this.superClass = superClass;
    }

    /**
     * Get the name of the super class.
     *
     * @return the name
     * @throws InvalidByteCodeException
     */
    public String getSuperClassName() throws InvalidByteCodeException {
        return getConstantPoolEntryName(getSuperClass());
    }

    /**
     * Get the array with the constant pool entries of all interfaces.
     *
     * @return the array
     */
    public int[] getInterfaces() {
        return interfaces;
    }

    /**
     * Set the array with the constant pool entries of all interfaces.
     *
     * @param interfaces the array
     */
    public void setInterfaces(int[] interfaces) {
        this.interfaces = interfaces;
    }

    /**
     * Get the array with the <tt>FieldInfo</tt> structures for the fields of this class.
     *
     * @return the array
     */
    public FieldInfo[] getFields() {
        return fields;
    }

    /**
     * Set the array with the <tt>FieldInfo</tt> structures for the fields of this class.
     *
     * @param fields the array
     */
    public void setFields(FieldInfo[] fields) {
        this.fields = fields;
    }

    /**
     * Get the array with the <tt>MethodInfo</tt> structures for the methods of this class.
     *
     * @return the array
     */
    public MethodInfo[] getMethods() {
        return methods;
    }

    /**
     * Set the array with the <tt>MethodInfo</tt> structures for the methods of this class.
     *
     * @param methods the array
     */
    public void setMethods(MethodInfo[] methods) {
        this.methods = methods;
    }

    /**
     * Get the the access flags of this class as a hex string.
     *
     * @return the hex string
     */
    public String getFormattedAccessFlags() {
        return printAccessFlags(accessFlags);
    }

    /**
     * Get the verbose description of the access flags of this class.
     *
     * @return the description
     */
    public String getAccessFlagsVerbose() {
        return printAccessFlagsVerbose(accessFlags);
    }

    /**
     * Get the <tt>ConstantUtf8Info</tt> constant pool entry at the specified index.
     *
     * @param index the index
     * @return the constant pool entry
     * @throws InvalidByteCodeException if the entry is not a <tt>ConstantUtf8Info</tt>
     */
    public ConstantUtf8Info getConstantPoolUtf8Entry(int index)
            throws InvalidByteCodeException {

        return (ConstantUtf8Info)getConstantPoolEntry(index, ConstantUtf8Info.class);
    }

    /**
     * Get the constant pool entry at the specified index.
     *
     * @param index      the index
     * @return the constant pool entry
     * @throws InvalidByteCodeException if the entry is of a different class than expected
     */
    public CPInfo getConstantPoolEntry(int index)
            throws InvalidByteCodeException {

        if (!checkValidConstantPoolIndex(index)) {
            return null;
        }

        CPInfo cpInfo = constantPool[index];

        
        return cpInfo;


    }    
    
    
    /**
     * Get the constant pool entry at the specified index and cast it to a specified class.
     *
     * @param index      the index
     * @param entryClass the required subtype of <tt>CPInfo</tt>
     * @return the constant pool entry
     * @throws InvalidByteCodeException if the entry is of a different class than expected
     */
    public CPInfo getConstantPoolEntry(int index, Class entryClass)
            throws InvalidByteCodeException {

        if (!checkValidConstantPoolIndex(index)) {
            return null;
        }

        CPInfo cpInfo = constantPool[index];

        if (cpInfo == null) {
            return null;
        }

        if (entryClass.isAssignableFrom(cpInfo.getClass())) {
            return cpInfo;
        } else {
            throw new InvalidByteCodeException("constant pool entry at " + index +
                    " is not assignable to " +
                    entryClass.getName());
        }
    }

    /**
     * Get an approximate verbose description of the content of the constant pool entry
     * at the specified index.
     *
     * @param index the index
     * @return the description

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -