class.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 514 行

JAVA
514
字号
/*
 *  java.lang.Class
 *
 *  (c) 1997 George David Morrison
 *
 *  API version: 1.0.2
 *
 *  History:
 *  01JAN1997  George David Morrison
 *    Initial version
 */

package java.lang;

import gnu.java.lang.ClassHelper;

import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;

import org.jnode.vm.SoftByteCodes;
import org.jnode.vm.VmReflection;
import org.jnode.vm.VmSystem;
import org.jnode.vm.classmgr.Signature;
import org.jnode.vm.classmgr.VmArrayClass;
import org.jnode.vm.classmgr.VmField;
import org.jnode.vm.classmgr.VmMethod;
import org.jnode.vm.classmgr.VmType;

/**
 * Class.
 * If you change any fields in this class, also change <code>emitClass</code>
 * in <code>org.jnode.build.ObjectEmitter</code>
 * @see org.jnode.build.ObjectEmitter#emitClass
 * @author epr
 */
public final class Class {

	private final VmType vmClass;
	private Constructor[] declaredConstructors;
	private Field[] declaredFields;
	private Method[] declaredMethods;
	private ArrayList fields;
	private ArrayList methods;
	private ArrayList interfaces;
	private VmMethod defaultConstructor;
	private String name;

	/**
	 * Create a new instance.
	 * This constructor can be public, because the creation of VmClass instances
	 * of already protected.
	 * @param vmClass
	 */
	public Class(VmType vmClass) {
		if (vmClass == null) {
			throw new IllegalArgumentException("vmClass cannot be null");
		}
		this.vmClass = vmClass;
	}

	public static Class forName(String className) throws ClassNotFoundException {
		//System.out.println("Class.forName [" + className + "]");

		return VmSystem.forName(className);
	}

	public static Class forName(String className, boolean initialize, ClassLoader loader) throws ClassNotFoundException {
		return VmSystem.forName(className);
	}

	/**
	 * Converts this object to its String representation
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return (isInterface() ? "interface " : "class ") + getName();
	}

	public boolean desiredAssertionStatus() {
		return true;
	}

	/**
	 * Gets the name of this class
	 * @return String
	 */
	public String getName() {
		if (name == null) {
			name = vmClass.getName().replace('/', '.');
		}
		return name;
	}

	/**
	 * Is this class an interface?
	 * @return boolean
	 */
	public boolean isInterface() {
		return vmClass.isInterface();
	}

	/**
	 * Gets the Class this class extends, or null if this class is <code>java.lang. Object</code>
	 * @return Class
	 */
	public final Class getSuperclass() {
		VmType superCls = vmClass.getSuperClass();
		if (superCls != null) {
			return superCls.asClass();
		} else {
			return null;
		}
	}

	/**
	 * Determines the interfaces implemented by the class or interface represented by this object.
	 * @return Class[]
	 */
	public final Class[] getInterfaces() {
		if (interfaces == null) {
			ArrayList list = new ArrayList();
			int cnt = vmClass.getNoInterfaces();
			for (int i = 0; i < cnt; i++) {
				list.add(vmClass.getInterface(i).asClass());
			}
			interfaces = list;
		}
		return (Class[]) interfaces.toArray(new Class[interfaces.size()]);
	}

	/**
	 * Is the given object instanceof this class.
	 * @param object
	 * @return boolean
	 */
	public boolean isInstance(Object object) {
		return SoftByteCodes.isInstanceof(object, vmClass);
	}

	/**
	 * Discover whether an instance of the Class parameter would be an
	 * instance of this Class as well.  Think of doing
	 * <code>isInstance(c.newInstance())</code> or even
	 * <code>c.newInstance() instanceof (this class)</code>. While this
	 * checks widening conversions for objects, it must be exact for primitive
	 * types.
	 *
	 * @param c the class to check
	 * @return whether an instance of c would be an instance of this class
	 *         as well
	 * @throws NullPointerException if c is null
	 * @since 1.1
	 */
	public boolean isAssignableFrom(Class c) {
		return vmClass.isAssignableFrom(c.vmClass);
	}

	/**
	 * Gets the classloader used to load this class.
	 * @return ClassLoader
	 */
	public final ClassLoader getClassLoader() {
		return vmClass.getLoader().asClassLoader();
	}

	/**
	 * Create a new instance of this class, using the default constructor
	 * @return Object
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public final Object newInstance() throws InstantiationException, IllegalAccessException {
		if (defaultConstructor == null) {
			defaultConstructor = vmClass.getDeclaredMethod("<init>", "()V");
		}
		try {
			return VmReflection.newInstance(defaultConstructor);
		} catch (InvocationTargetException ex) {
			return new InstantiationException(ex);
		}
	}

	/**
	 * Gets the modifiers of this class
	 * @return int
	 */
	public final int getModifiers() {
		return vmClass.getAccessFlags();
	}

	/**
	 * Gets the field with the given name that is declared in this class or any of my super-classes.
	 * @param name
	 * @return Field
	 * @throws NoSuchFieldException
	 * @throws SecurityException
	 */
	public Field getField(String name) throws NoSuchFieldException, SecurityException {
		VmField f = vmClass.getField(name);
		if (f != null) {
			return f.asField();
		} else {
			throw new NoSuchFieldException(name);
		}
	}

	/**
	 * Gets all fields declared in this class and all of its super-classes.
	 * @return Field[]
	 */
	public Field[] getFields() {
		if (fields == null) {
			ArrayList list = new ArrayList();
			Class cls = this;
			while (cls != null) {
				final Field[] dlist = cls.getDeclaredFields();
				for (int i = 0; i < dlist.length; i++) {
					list.add(dlist[i]);
				}
				cls = cls.getSuperclass();
			}
			fields = list;
		}
		return (Field[]) fields.toArray(new Field[fields.size()]);
	}

	/**
	 * Gets the field with the given name that is declared in this class.
	 * @param name
	 * @return Field
	 * @throws NoSuchFieldException
	 * @throws SecurityException
	 */
	public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException {
		VmField f = vmClass.getDeclaredField(name);
		if (f != null) {
			return f.asField();
		} else {
			throw new NoSuchFieldException(name);
		}
	}

	/**
	 * Gets all fields declared in this class
	 * @return Field[]
	 */
	public Field[] getDeclaredFields() {
		if (declaredFields == null) {
			int cnt = vmClass.getNoDeclaredFields();
			Field[] list = new Field[cnt];
			for (int i = 0; i < cnt; i++) {
				list[i] = vmClass.getDeclaredField(i).asField();
			}
			declaredFields = list;
		}
		return declaredFields;
	}

	/**
	 * Is this class a primitive class?
	 * @return boolean
	 */
	public boolean isPrimitive() {
		return vmClass.isPrimitive();
	}

	/**
	 * Return the class of my components (if this class is an array)
	 * @return Class
	 */
	public Class getComponentType() {
		if (vmClass instanceof VmArrayClass) {
			final VmType vmCompType = ((VmArrayClass) vmClass).getComponentType();
			if (vmCompType != null) {
				return vmCompType.asClass();
			}
		}
		return null;
	}

	/**
	 * Gets the method with the given name and argument types declared in this class
	 * or any of its super-classes.
	 * @param name
	 * @param argTypes
	 * @return Method
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 */
	public Method getMethod(String name, Class[] argTypes) throws NoSuchMethodException, SecurityException {
		VmType[] vmArgTypes;
		if (argTypes == null) {
			vmArgTypes = null;
		} else {
			final int cnt = argTypes.length;
			vmArgTypes = new VmType[cnt];
			for (int i = 0; i < cnt; i++) {
				vmArgTypes[i] = argTypes[i].vmClass;
			}
		}
		VmMethod method = vmClass.getMethod(name, vmArgTypes);
		if (method != null) {
			return (Method) method.asMember();
		} else {
			throw new NoSuchMethodException(name);
		}
	}

	/**
	 * Gets all methods declared in this class and its super-classes
	 * @return Method[]
	 */
	public Method[] getMethods() {
		if (methods == null) {
			ArrayList list = new ArrayList();
			Class cls = this;
			while (cls != null) {
				final Method[] dlist = cls.getDeclaredMethods();
				for (int i = 0; i < dlist.length; i++) {
					list.add(dlist[i]);
				}
				cls = cls.getSuperclass();
			}
			methods = list;
		}
		return (Method[]) methods.toArray(new Method[methods.size()]);
	}

	/**
	 * Gets the method with the given name and argument types declared in this class.
	 * @param name
	 * @param argTypes
	 * @return Method
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 */
	public Method getDeclaredMethod(String name, Class[] argTypes) throws NoSuchMethodException, SecurityException {
		VmType[] vmArgTypes;
		if (argTypes == null) {
			vmArgTypes = null;
		} else {
			final int cnt = argTypes.length;
			vmArgTypes = new VmType[cnt];
			for (int i = 0; i < cnt; i++) {
				vmArgTypes[i] = argTypes[i].vmClass;
			}
		}
		VmMethod method = vmClass.getDeclaredMethod(name, vmArgTypes);
		if (method != null) {
			return (Method) method.asMember();
		} else {
			throw new NoSuchMethodException(name);
		}
	}

	/**
	 * Gets all methods declared in this class.
	 * @return Method[]
	 */
	public Method[] getDeclaredMethods() {
		if (declaredMethods == null) {
			int cnt = vmClass.getNoDeclaredMethods();
			int max = 0;
			for (int i = 0; i < cnt; i++) {
				if (!vmClass.getDeclaredMethod(i).isConstructor()) {
					max++;
				}
			}
			Method[] list = new Method[max];
			max = 0;
			for (int i = 0; i < cnt; i++) {
				VmMethod vmMethod = vmClass.getDeclaredMethod(i);
				if (!vmMethod.isConstructor()) {
					list[max++] = (Method) vmMethod.asMember();
				}
			}
			declaredMethods = list;
		}
		return declaredMethods;
	}

	public Constructor getDeclaredConstructor(Class[] argTypes) {
		return null;
	}

	/**
	 * Gets all constructors declared in this class
	 * @return Constructor[]
	 */
	public Constructor[] getDeclaredConstructors() {
		if (declaredConstructors == null) {
			int cnt = vmClass.getNoDeclaredMethods();
			int max = 0;
			for (int i = 0; i < cnt; i++) {
				if (vmClass.getDeclaredMethod(i).isConstructor()) {
					max++;
				}
			}
			Constructor[] list = new Constructor[max];
			max = 0;
			for (int i = 0; i < cnt; i++) {
				VmMethod vmMethod = vmClass.getDeclaredMethod(i);
				if (vmMethod.isConstructor()) {
					list[max++] = (Constructor) vmMethod.asMember();
				}
			}
			declaredConstructors = list;
		}
		return declaredConstructors;
	}

	public Package getPackage() {
		return null;
	}

	/**
	 * Is this class an array class?
	 * @return boolean
	 */
	public boolean isArray() {
		return vmClass.isArray();
	}

	/**
	 * Gets the constructor with the given argument types.
	 * @param argTypes
	 * @return Constructor
	 * @throws NoSuchMethodException
	 */
	public Constructor getConstructor(Class[] argTypes) throws NoSuchMethodException {
		String signature = Signature.toSignature(null, argTypes);
		VmMethod vmMethod = vmClass.getMethod("<init>", signature);
		if (vmMethod != null) {
			return (Constructor) vmMethod.asMember();
		} else {
			throw new NoSuchMethodException("<init> " + signature);
		}
	}

	/**
	 * Get a resource URL using this class's package using the
	 * getClassLoader().getResource() method.  If this class was loaded using
	 * the system classloader, ClassLoader.getSystemResource() is used instead.
	 *
	 * <p>If the name you supply is absolute (it starts with a <code>/</code>),
	 * then it is passed on to getResource() as is.  If it is relative, the
	 * package name is prepended, and <code>.</code>'s are replaced with
	 * <code>/</code>.
	 *
	 * <p>The URL returned is system- and classloader-dependent, and could
	 * change across implementations.
	 *
	 * @param name the name of the resource, generally a path
	 * @return the URL to the resource
	 * @throws NullPointerException if name is null
	 * @since 1.1
	 */
	public URL getResource(String name) {
		if (name.length() > 0 && name.charAt(0) != '/') {
			name = ClassHelper.getPackagePortion(getName()).replace('.', '/') + "/" + name;
		}
		final ClassLoader ld = getClassLoader();
		if (ld != null) {
			return ld.getResource(name);
		} else {
			return ClassLoader.getSystemResource(name);
		}
	}

	/**
	 * Get a resource using this class's package using the
	 * getClassLoader().getResourceAsStream() method.  If this class was loaded
	 * using the system classloader, ClassLoader.getSystemResource() is used
	 * instead.
	 *
	 * <p>If the name you supply is absolute (it starts with a <code>/</code>),
	 * then it is passed on to getResource() as is.  If it is relative, the
	 * package name is prepended, and <code>.</code>'s are replaced with
	 * <code>/</code>.
	 *
	 * <p>The URL returned is system- and classloader-dependent, and could
	 * change across implementations.
	 *
	 * @param name the name of the resource, generally a path
	 * @return an InputStream with the contents of the resource in it, or null
	 * @throws NullPointerException if name is null
	 * @since 1.1
	 */
	public InputStream getResourceAsStream(String name) {
		if (name.length() > 0 && name.charAt(0) != '/') {
			name = ClassHelper.getPackagePortion(getName()).replace('.', '/') + "/" + name;
		}
		final ClassLoader ld = getClassLoader();
		if (ld != null) {
			return ld.getResourceAsStream(name);
		} else {
			return ClassLoader.getSystemResourceAsStream(name);
		}
	}

	public VmType getVmClass() {
		return vmClass;
	}

	static Class getPrimitiveClass(char type) {
		return VmType.getPrimitiveClass(type).asClass();
	}
}

⌨️ 快捷键说明

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