classinfo.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 1,142 行 · 第 1/3 页

JAVA
1,142
字号
/* * @(#)ClassInfo.java	1.48 06/10/22 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */package components;import jcc.Util;import jcc.Str2ID;import consts.Const;import util.*;import java.io.DataInput;import java.io.DataOutput;import java.io.IOException;import java.io.PrintStream;import java.util.Enumeration;import java.util.Hashtable;import java.util.Set;import java.util.Vector;/** * ClassInfo is the root of all information about the class * which comes out of the .class file, including its methods, * fields, interfaces, superclass, and any other attributes we * read in. * ClassInfo does not contain (in theory) any VM-specific data. * All the target-VM-specific information is kept in the corresponding * ClassClass: see field vmClass. ClassClass is abstract, so what is * really present is a target-VM-specific subclass of it, such as CVMClass. */publicclass ClassInfo{    public int                  majorVersion;    public int                  minorVersion;	    public String		className;    public int			access;    public ClassConstant	thisClass;    public ClassConstant	superClass;    public ClassInfo		superClassInfo;    // Tables for all fields, methods and constants of this class    public FieldInfo		fields[];    public MethodInfo		methods[];    private static ConstantPool	nullCP =	new ConstantPool(new ConstantObject[0]);    private ConstantPool	cp = nullCP;    private ConstantObject	oldConstants[];    public ClassConstant	interfaces[];    // These are the tables of instance fields and methods.    // The methodtable is turned into the virtual method lookup table    // of the virtual machine.    public FieldInfo		fieldtable[];    public MethodInfo		methodtable[];    /*     * Info on each slot of an object, indexed by offset     * instead of on its field #     * The difference between fieldtable and slottable is slight     * -- its just that double-word fields (types J and D) take     * up 2 entries in the slottable.     */    public FieldInfo		slottable[];    // Class attributes that we do not interpret    public Attribute[]          classAttributes;    public SourceFileAttribute  sourceFileAttr;    // Innerclass attribute accessed.    public InnerClassAttribute	innerClassAttr;    // Class generics signature info:    public SignatureAttribute   signatureAttr;    public ClassLoader		loader;    public vm.ClassClass	vmClass; // used by in-core output writers    public Vector		allInterfaces;    protected boolean		verbose;    protected static PrintStream log = System.out;    public  static boolean      classDebug = false;    public int			flags;    public static final int	INCLUDE_ALL = 1;    public int			group;        public static int finalizerID = Str2ID.sigHash.getID(						/*NOI18N*/"finalize", /*NOI18N*/"()V" );    public boolean              hasNonTrivialFinalizer = false;    private int			pkgNameLength;    private final char		SIGC_PACKAGE = util.ClassFileConst.SIGC_PACKAGE;    public ClassInfo( boolean v ) {        Assert.assertClassloadingIsAllowed();	verbose = v;	flags = INCLUDE_ALL; // by default, we want all members.	// what else should be here?    }    private String genericNativeName;    public final String getGenericNativeName() {         if (genericNativeName == null) 	    genericNativeName = createGenericNativeName();        return genericNativeName;    }    public boolean isFinal() {	return ((access & Const.ACC_FINAL) != 0);    }        // Is this class a subclass of java.lang.ref.Reference?    public boolean isReference() {	ClassInfo cinfo = this;	while (cinfo != null) {	    if (cinfo.className.equals("java/lang/ref/Reference")) {		return true;	    }	    cinfo = cinfo.superClassInfo;	}	return false;    }    // Is this class an interface?    public boolean isInterface() {	return ((this.access & Const.ACC_INTERFACE) != 0);    }    // Is this class the java.lang.Object class?    public boolean isJavaLangObject() {	ClassInfo cinfo = this;	if ((cinfo != null) && cinfo.className.equals("java/lang/Object")) {	    return true;	}	return false;    }    // This will be overridden by subclasses    protected String createGenericNativeName() {         return Util.convertToClassName(className );    }    /**     * Reads in the constant pool from a classfile, and fills in the cp     * (i.e. constantpool) field of this classinfo instance.  The filled in     * constants are not yet in a resolved state.     */    private void readConstantPool(DataInput in) throws IOException {	int num = in.readUnsignedShort();	if(verbose){	    log.println(Localizer.getString(                "classinfo.reading_entries_in_constant_pool",                Integer.toString(num)));	}	ConstantObject[] constants = new ConstantObject[num];	for (int i = 1; i < num; i+=constants[i].nSlots) {	    constants[i] = ConstantObject.readObject(in);	    constants[i].index = i;	    constants[i].containingClass = this;	}	cp = new ConstantPool(constants);    }    /**     * Flatten all CP entries so that they need not indirect through the     * constant pool to get to the symbollic info.  For example, a class     * constant is defined by a CP index which point to a UTF8 string.  A     * flattened class constant will refer to the UTF8 string directly instead     * of needing to index into the constant pool to get to it.     */    private void flattenConstants() {	if (verbose) {            log.println(Localizer.getString(                            "classinfo.>>>resolving_constants"));	}	ConstantObject constants[] = cp.getConstants();	for (int i = 1; i < constants.length; i+=constants[i].nSlots) {	    constants[i].flatten(cp);	}    }    /*     * Iterate through the constant pool.     * Look for class constants that don't point to anything, yet.     * Put those String names in the undefClasses set.     */    public void    findUndefinedClasses(Set undefClasses) {	ConstantObject constants[] = cp.getConstants();	for (int i = 1; i < constants.length; i+=constants[i].nSlots) {	    if (constants[i].tag == Const.CONSTANT_CLASS) {		ClassConstant c = (ClassConstant) constants[i];		if (c.find() == null){		    String stringname = c.name.string;		    c.forget();		    if (stringname.charAt(0) == '['){			// this is an array.			// DO NOT put the array in the table.			// but we may need to put an underlying			// object type in, so take a closer look.			int lindex = stringname.indexOf('L');			if (lindex == -1){			    // primitive array type. 			    // not interesting.			    continue;			}			// capture the name between the L and the ;			stringname = stringname.substring(					lindex+1, stringname.length()-1);			if (loader.lookupClass(stringname) != null){			    continue; // found it.			}		    }		    undefClasses.add(stringname);		}	    }	}    }        /*     * we can make our own table smaller by deleting unreferenced elements.     * At this point,     * all non-code references into it are by object reference, NEVER     * by index -- everything has been resolved! Thus we can     * compact our table, deleting all the UnicodeConstants.     * We adjust each constant's index entry accordingly.     * Naturally, we preserve the null entries.     */    public void smashConstantPool() {	ConstantObject constants[] = cp.getConstants();	int nOld = constants.length;	int nNew = 1;	ConstantObject o;	// first, count and index.	for (int i = 1; i < nOld; i += o.nSlots) {	    o = constants[i];	    if (!o.shared) {		if (o.getReferences() == 0) {		    o.index = -1; // trouble.		} else {		    // we're keeping it.		    o.index = nNew;		    nNew += o.nSlots;		}	    }	}	// now reallocate and copy.	ConstantObject newConstants[] = new ConstantObject[ nNew ];	int j = 1;	for (int i = 1; i < nOld; i += o.nSlots) {	    o = constants[i];	    if (!o.shared && (o.getReferences() != 0)) {		// we're keeping it.		newConstants[j] = o;		j += o.nSlots;	    }	}	oldConstants = constants;	cp = new ConstantPool(newConstants);    }    public ConstantPool getConstantPool() {	return cp;    }    public void setConstantPool(ConstantPool c) {	cp = c;    }    // Read the list of interfaces this class supports    void readInterfaces( DataInput in ) throws IOException {	int count = in.readUnsignedShort();	if(verbose){	    log.println(Localizer.getString(		"classinfo.reading_interfaces_implemented", Integer.toString(count)));	}	interfaces = new ClassConstant[count];	ConstantObject constants[] = cp.getConstants();	for (int i = 0; i < count; i++) {	    interfaces[i] = (ClassConstant) constants[in.readUnsignedShort()];	}    }    // Read the list of fields    void readFields( DataInput in ) throws IOException {	int count = in.readUnsignedShort();	fields = new FieldInfo[count];	if(verbose){	    log.println(Localizer.getString("classinfo.reading_field_members", Integer.toString(count)));	}        int i, j;	for (i = j = 0; i < count; i++) {            FieldInfo fi = FieldInfo.readField(in, this);            if (fi != null) {                fields[j] = fi;                fields[j].index = j;                fields[j++].captureValueAttribute();            }	}        // If we have discarded any fields, re-create the table.        if (j != i) {            FieldInfo[] smaller = new FieldInfo[j];            System.arraycopy(fields, 0, smaller, 0, j);            fields = smaller;        }    }    // Read the list of methods from classfile    void readMethods( DataInput in, boolean readCode ) throws IOException {	int count = in.readUnsignedShort();	methods = new MethodInfo[count];	if(verbose){	    log.println(Localizer.getString(			"classinfo.reading_methods", Integer.toString(count)));	}        int i, j;	for (i = j = 0; i < count; i++) {            MethodInfo mi = MethodInfo.readMethod( in, this, readCode );            if (mi != null) {                methods[j] = mi;                methods[j].index = j++;            }	}        // If we have discarded any methods, re-create the table.        if ( j != i ) {            MethodInfo[] smaller = new MethodInfo[j];            System.arraycopy(methods, 0, smaller, 0, j);            methods = smaller;        }    }    void readAttributes( DataInput in ) throws IOException {	int count = in.readUnsignedShort();	Vector clssAttr = new Vector();		if(verbose){	    log.println(Localizer.getString("classinfo.reading_attributes", Integer.toString(count)));	}	ConstantObject constants[] = cp.getConstants();	for (int i = 0; i < count; i++) {	    int nameIndex = in.readUnsignedShort();	    int bytes = in.readInt();	    UnicodeConstant name = (UnicodeConstant)constants[nameIndex];

⌨️ 快捷键说明

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