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

📄 classfile.java

📁 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Javassist, a Java-bytecode translator toolkit. * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License.  Alternatively, the contents of this file may be used under * the terms of the GNU Lesser General Public License Version 2.1 or later. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. */package javassist.bytecode;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.util.ArrayList;import java.util.LinkedList;import java.util.List;import java.util.ListIterator;import java.util.Map;import javassist.CannotCompileException;/** * <code>ClassFile</code> represents a Java <code>.class</code> file, which * consists of a constant pool, methods, fields, and attributes. *  * @see javassist.CtClass#getClassFile() */public final class ClassFile {    int major, minor; // version number    ConstPool constPool;    int thisClass;    int accessFlags;    int superClass;    int[] interfaces;    ArrayList fields;    ArrayList methods;    LinkedList attributes;    String thisclassname; // not JVM-internal name    String[] cachedInterfaces;    String cachedSuperclass;    /**     * Constructs a class file from a byte stream.     */    public ClassFile(DataInputStream in) throws IOException {        read(in);    }    /**     * Constructs a class file including no members.     *      * @param isInterface     *            true if this is an interface. false if this is a class.     * @param classname     *            a fully-qualified class name     * @param superclass     *            a fully-qualified super class name     */    public ClassFile(boolean isInterface, String classname, String superclass) {        major = 45;        minor = 3; // JDK 1.1 or later        constPool = new ConstPool(classname);        thisClass = constPool.getThisClassInfo();        if (isInterface)            accessFlags = AccessFlag.SUPER | AccessFlag.INTERFACE                    | AccessFlag.ABSTRACT;        else            accessFlags = AccessFlag.SUPER;        initSuperclass(superclass);        interfaces = null;        fields = new ArrayList();        methods = new ArrayList();        thisclassname = classname;        attributes = new LinkedList();        attributes.add(new SourceFileAttribute(constPool,                getSourcefileName(thisclassname)));    }    private void initSuperclass(String superclass) {        if (superclass != null) {            this.superClass = constPool.addClassInfo(superclass);            cachedSuperclass = superclass;        }        else {            this.superClass = constPool.addClassInfo("java.lang.Object");            cachedSuperclass = "java.lang.Object";        }    }    private static String getSourcefileName(String qname) {        int index = qname.lastIndexOf('.');        if (index >= 0)            qname = qname.substring(index + 1);        return qname + ".java";    }    /**     * Eliminates dead constant pool items. If a method or a field is removed,     * the constant pool items used by that method/field become dead items. This     * method recreates a constant pool.     */    public void compact() {        ConstPool cp = compact0();        ArrayList list = methods;        int n = list.size();        for (int i = 0; i < n; ++i) {            MethodInfo minfo = (MethodInfo)list.get(i);            minfo.compact(cp);        }        list = fields;        n = list.size();        for (int i = 0; i < n; ++i) {            FieldInfo finfo = (FieldInfo)list.get(i);            finfo.compact(cp);        }        attributes = AttributeInfo.copyAll(attributes, cp);        constPool = cp;    }    private ConstPool compact0() {        ConstPool cp = new ConstPool(thisclassname);        thisClass = cp.getThisClassInfo();        String sc = getSuperclass();        if (sc != null)            superClass = cp.addClassInfo(getSuperclass());        if (interfaces != null) {            int n = interfaces.length;            for (int i = 0; i < n; ++i)                interfaces[i]                    = cp.addClassInfo(constPool.getClassInfo(interfaces[i]));        }        return cp;    }    /**     * Discards all attributes, associated with both the class file and the     * members such as a code attribute and exceptions attribute. The unused     * constant pool entries are also discarded (a new packed constant pool is     * constructed).     */    public void prune() {        ConstPool cp = compact0();        LinkedList newAttributes = new LinkedList();        AttributeInfo invisibleAnnotations            = getAttribute(AnnotationsAttribute.invisibleTag);        if (invisibleAnnotations != null) {            invisibleAnnotations = invisibleAnnotations.copy(cp, null);            newAttributes.add(invisibleAnnotations);        }        AttributeInfo visibleAnnotations            = getAttribute(AnnotationsAttribute.visibleTag);        if (visibleAnnotations != null) {            visibleAnnotations = visibleAnnotations.copy(cp, null);            newAttributes.add(visibleAnnotations);        }        ArrayList list = methods;        int n = list.size();        for (int i = 0; i < n; ++i) {            MethodInfo minfo = (MethodInfo)list.get(i);            minfo.prune(cp);        }        list = fields;        n = list.size();        for (int i = 0; i < n; ++i) {            FieldInfo finfo = (FieldInfo)list.get(i);            finfo.prune(cp);        }        attributes = newAttributes;        cp.prune();        constPool = cp;    }    /**     * Returns a constant pool table.     */    public ConstPool getConstPool() {        return constPool;    }    /**     * Returns true if this is an interface.     */    public boolean isInterface() {        return (accessFlags & AccessFlag.INTERFACE) != 0;    }    /**     * Returns true if this is a final class or interface.     */    public boolean isFinal() {        return (accessFlags & AccessFlag.FINAL) != 0;    }    /**     * Returns true if this is an abstract class or an interface.     */    public boolean isAbstract() {        return (accessFlags & AccessFlag.ABSTRACT) != 0;    }    /**     * Returns access flags.     *      * @see javassist.bytecode.AccessFlag     */    public int getAccessFlags() {        return accessFlags;    }    /**     * Changes access flags.     *      * @see javassist.bytecode.AccessFlag     */    public void setAccessFlags(int acc) {        accessFlags = acc | AccessFlag.SUPER;    }    /**     * Returns access and property flags of this nested class.     * This method returns -1 if the class is not a nested class.      *     * <p>The returned value is obtained from <code>inner_class_access_flags</code>     * of the entry representing this nested class itself     * in <code>InnerClasses_attribute</code>>.      */    public int getInnerAccessFlags() {        InnerClassesAttribute ica            = (InnerClassesAttribute)getAttribute(InnerClassesAttribute.tag);        if (ica == null)            return -1;        String name = getName();        int n = ica.tableLength();        for (int i = 0; i < n; ++i)            if (name.equals(ica.innerClass(i)))                return ica.accessFlags(i);        return -1;    }    /**     * Returns the class name.     */    public String getName() {        return thisclassname;    }    /**     * Sets the class name. This method substitutes the new name for all     * occurrences of the old class name in the class file.     */    public void setName(String name) {        renameClass(thisclassname, name);    }    /**     * Returns the super class name.     */    public String getSuperclass() {        if (cachedSuperclass == null)            cachedSuperclass = constPool.getClassInfo(superClass);        return cachedSuperclass;    }    /**     * Returns the index of the constant pool entry representing the super     * class.     */    public int getSuperclassId() {        return superClass;    }    /**     * Sets the super class.     *      * <p>     * This method modifies constructors so that they call constructors declared     * in the new super class.     */    public void setSuperclass(String superclass) throws CannotCompileException {        if (superclass == null)            superclass = "java.lang.Object";        try {            this.superClass = constPool.addClassInfo(superclass);            ArrayList list = methods;            int n = list.size();            for (int i = 0; i < n; ++i) {                MethodInfo minfo = (MethodInfo)list.get(i);                minfo.setSuperclass(superclass);            }        }        catch (BadBytecode e) {            throw new CannotCompileException(e);        }        cachedSuperclass = superclass;    }    /**     * Replaces all occurrences of a class name in the class file.     *      * <p>     * If class X is substituted for class Y in the class file, X and Y must     * have the same signature. If Y provides a method m(), X must provide it     * even if X inherits m() from the super class. If this fact is not     * guaranteed, the bytecode verifier may cause an error.     *      * @param oldname     *            the replaced class name     * @param newname     *            the substituted class name     */    public final void renameClass(String oldname, String newname) {        ArrayList list;        int n;        if (oldname.equals(newname))            return;        if (oldname.equals(thisclassname))            thisclassname = newname;        oldname = Descriptor.toJvmName(oldname);        newname = Descriptor.toJvmName(newname);        constPool.renameClass(oldname, newname);        list = methods;        n = list.size();        for (int i = 0; i < n; ++i) {            MethodInfo minfo = (MethodInfo)list.get(i);            String desc = minfo.getDescriptor();            minfo.setDescriptor(Descriptor.rename(desc, oldname, newname));        }        list = fields;        n = list.size();        for (int i = 0; i < n; ++i) {            FieldInfo finfo = (FieldInfo)list.get(i);            String desc = finfo.getDescriptor();            finfo.setDescriptor(Descriptor.rename(desc, oldname, newname));        }    }    /**     * Replaces all occurrences of several class names in the class file.     *      * @param classnames     *            specifies which class name is replaced with which new name.     *            Class names must be described with the JVM-internal     *            representation like <code>java/lang/Object</code>.     * @see #renameClass(String,String)     */    public final void renameClass(Map classnames) {        String jvmNewThisName = (String)classnames.get(Descriptor                .toJvmName(thisclassname));        if (jvmNewThisName != null)            thisclassname = Descriptor.toJavaName(jvmNewThisName);        constPool.renameClass(classnames);

⌨️ 快捷键说明

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