innerclassattribute.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 277 行

JAVA
277
字号
/* * @(#)InnerClassAttribute.java	1.13 06/10/10 * * 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 java.io.DataInput;import java.io.DataOutput;import java.io.IOException;import java.util.Enumeration;import java.util.Vector;/* * A class to represent the innerclass attribute of a class. The innerclass * attribute is new in 1.2 and is documented in the 1.2 JVM Spec. */publicclass InnerClassAttribute extends Attribute {//__________ CLASS METHODS    public static Attribute    readAttribute(DataInput in, int len,                  UnicodeConstant name,                  ConstantObject constants[]) throws IOException {	return finishReadAttribute(in, len, name, constants);    }    public static Attribute    finishReadAttribute(DataInput in, int len,                        UnicodeConstant name,                        ConstantObject constants[]) throws IOException {	int num        = in.readUnsignedShort();	Vector entries = new Vector(num);	int i, next, anonNum;	ClassConstant innerInfo;	ClassConstant outerInfo;	UnicodeConstant innerName;	for (i=0, anonNum=1; i < num; i++) {	    innerInfo = (ClassConstant)constants[in.readUnsignedShort()];	    outerInfo = (ClassConstant)constants[in.readUnsignedShort()];	    next = in.readUnsignedShort();	    if (next == 0) { // A zero value means this is an anonymous inner class.		// Note: We are guessing at the name of the anonymous class.		// But the guess will only be the correct name if the ordering		// of the inner class attributes is the same as the ordering		// of the anonymous inner classes as they appear in the source		// file. And that is totally dependent on how the javac compiler		// wants to do it. There is nothing in the JVM spec that says it		// has to be that way. This won't hurt anything since we are just		// replacing an unused name field with a guess. The JVM doesn't		// care what is in this field.		innerName = new UnicodeConstant((new Integer(anonNum++)).toString());	    } else {		innerName = (UnicodeConstant)constants[next];	    }	    	    entries.addElement(new InnerClassEntry(innerInfo,	                                           outerInfo,	                                           innerName,	                                           in.readUnsignedShort()));//	    entries.add(new InnerClassEntry(innerInfo,//	                                    outerInfo,//	                                    innerName,//	                                    in.readUnsignedShort()));	}			return new InnerClassAttribute(name, len, entries);    }//__________ INSTANCE VARIABLES    private Vector myInnerClassesVector;    private InnerClassEntry myInnerClassesArray[];//__________ CONSTRUCTORS    public    InnerClassAttribute(UnicodeConstant name,                        int len,                        Vector entries) {	super(name, len);	myInnerClassesVector = entries;	// Save an array copy because some methods use an index value	// to find individual entries. But don't forget to update this	// array if the vector changes, like in the removeEntry method.	myInnerClassesArray = new InnerClassEntry[myInnerClassesVector.size()];//	myInnerClassesVector.toArray(myInnerClassesArray);	myInnerClassesVector.copyInto(myInnerClassesArray);    }//__________ INSTANCE METHODS    protected int    writeData(DataOutput o) throws IOException {	int numberOfInnerClasses = myInnerClassesVector.size();	o.writeShort(numberOfInnerClasses);		Enumeration e = myInnerClassesVector.elements();	while (e.hasMoreElements()) {	    ((InnerClassEntry)e.nextElement()).write(o);	}			//return total number of bytes written, which is equal to	//2 (the number of bytes of the numberOfInnerClasses local	//variable) + the size of the InnerClassEntry * the number	//of inner classes.	return 2 + InnerClassEntry.SIZE * numberOfInnerClasses;    }    public void    mergeConstantsIntoSharedPool(ConstantPool sharedCP)    {	InnerClassEntry ice;	Enumeration e = myInnerClassesVector.elements();	while (e.hasMoreElements()) {	    ice = (InnerClassEntry)e.nextElement();	    if (ice.innerInfo != null) {		ice.innerInfo = (ClassConstant)sharedCP.add(ice.innerInfo);	    }	    if (ice.outerInfo != null) {		ice.outerInfo = (ClassConstant)sharedCP.add(ice.outerInfo);	    }	}	// Don't forget to update the array copy now that we've changed	// the vector.	myInnerClassesVector.copyInto(myInnerClassesArray);    }    /*     * I am unsure exactly how this should operate. If innerInfo is null,     * should I still check the values of outerInfo and innerName? I would     * think that it wouldn't matter because if innerInfo is null, the other     * two should also be null.     */    public void    countConstantReferences(boolean isRelocatable) {	super.countConstantReferences(isRelocatable);	InnerClassEntry ice;	Enumeration e = myInnerClassesVector.elements();	while (e.hasMoreElements()) {	    ice = (InnerClassEntry)e.nextElement();	    if (ice.innerInfo != null) {		ice.innerInfo.incReference();	    }	    if (ice.outerInfo != null) {		ice.outerInfo.incReference();	    }	    /* 	     * innerNameIndex not supported because utf8 cp entries	     * are not kept around.	     * 	    if (ice.innerName != null) {		ice.innerName.incReference();	    }	    */	}	// Don't forget to update the array copy now that we've changed	// the vector. 	myInnerClassesVector.copyInto(myInnerClassesArray);    }    /*     * This method only called just before writing output.     * Make sure that all our ClassConstant entries end up in a constant     * pool. Call super.validate so it can check its fields, too.     */    public void    validate(){	super.validate();	InnerClassEntry ice;	Enumeration e = myInnerClassesVector.elements();	while (e.hasMoreElements()) {	    ice = (InnerClassEntry)e.nextElement();	    if (ice.innerInfo != null) {		ice.innerInfo.validate();	    }	    if (ice.outerInfo != null) {		ice.outerInfo.validate();	    }	}    }    public void    removeEntry(int i) {System.out.println("*** Removing inner class "+ myInnerClassesArray[i].getFullName());//	myInnerClassesVector.remove(myInnerClassesArray[i]);	myInnerClassesVector.removeElement(myInnerClassesArray[i]);		// Don't forget to update the array copy now that we've changed	// the vector.	myInnerClassesArray = new InnerClassEntry[myInnerClassesVector.size()];//	myInnerClassesVector.toArray(myInnerClassesArray);	myInnerClassesVector.copyInto(myInnerClassesArray);    }	        public int    getInnerClassCount() {	return myInnerClassesVector.size();    }        /*     * The following four methods return information about individual     * inner class entries contained in this attribute. These methods     * call corresponding methods in the InnerClassEntry class. They     * are self-explanatory.     */    public int    getInnerInfoIndex(int i) {		return myInnerClassesArray[i].getInnerInfoIndex();    }    public int    getOuterInfoIndex(int i) {	return myInnerClassesArray[i].getOuterInfoIndex();    }    public int    getInnerNameIndex(int i) {		return myInnerClassesArray[i].getInnerNameIndex();    }        public int    getAccessFlags(int i) {		return myInnerClassesArray[i].getAccessFlags();    }        /*     * Like the above methods, these methods return information about     * an individual inner class entry. The string returned will be     * the name of the inner class, if it has one. If the inner class     * is anonymous, it will not have a name and the string "anonymous"     * will be returned.     */    public String    getName(int i) {	return myInnerClassesArray[i].getName();    }        /*     * Like the getName method, but return the outer class name as well.     */    public String    getFullName(int i) {	return myInnerClassesArray[i].getFullName();    }}

⌨️ 快捷键说明

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