Index: java/lang/Class.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/Class.java,v
retrieving revision 1.12
diff -u -b -B -r1.12 Class.java
--- java/lang/Class.java 25 Jan 2004 14:11:24 -0000 1.12
+++ java/lang/Class.java 25 Jan 2004 14:48:12 -0000
@@ -202,188 +202,34 @@
}
/**
- * Get a new instance of this class by calling the no-argument constructor.
- * The class is initialized if it has not been already. A security check
- * may be performed, with checkMemberAccess(this, Member.PUBLIC)
- * as well as checkPackageAccess
both having to succeed.
+ * Get all the public member classes and interfaces declared in this
+ * class or inherited from superclasses. This returns an array of length
+ * 0 if there are no member classes, including for primitive types. A
+ * security check may be performed, with
+ * checkMemberAccess(this, Member.PUBLIC)
as well as
+ * checkPackageAccess
both having to succeed.
*
- * @return a new instance of this class
- * @throws InstantiationException if there is not a no-arg constructor
- * for this class, including interfaces, abstract classes, arrays,
- * primitive types, and void; or if an exception occurred during
- * the constructor
- * @throws IllegalAccessException if you are not allowed to access the
- * no-arg constructor because of scoping reasons
+ * @return all public member classes in this class
* @throws SecurityException if the security check fails
- * @throws ExceptionInInitializerError if class initialization caused by
- * this call fails with an exception
- */
- public Object newInstance()
- throws InstantiationException, IllegalAccessException
- {
- memberAccessCheck(Member.PUBLIC);
- Constructor constructor;
- synchronized(this)
- {
- constructor = this.constructor;
- }
- if (constructor == null)
- {
- Constructor[] constructors = getDeclaredConstructors(false);
- for (int i = 0; i < constructors.length; i++)
- {
- if (constructors[i].getParameterTypes().length == 0)
- {
- constructor = constructors[i];
- break;
- }
- }
- if (constructor == null)
- throw new InstantiationException(getName());
- if (!Modifier.isPublic(constructor.getModifiers()))
- {
- final Constructor finalConstructor = constructor;
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- finalConstructor.setAccessible(true);
- return null;
- }
- });
- }
- synchronized(this)
- {
- if (this.constructor == null)
- this.constructor = constructor;
- }
- }
- int modifiers = constructor.getModifiers();
- if (!Modifier.isPublic(modifiers))
- {
- Class caller = VMSecurityManager.getClassContext()[1];
- if (caller != this &&
- (Modifier.isPrivate(modifiers)
- || getClassLoader() != caller.getClassLoader()
- || !getPackagePortion(getName())
- .equals(getPackagePortion(caller.getName()))))
- throw new IllegalAccessException(getName()
- + " has an inaccessible constructor");
- }
- try
- {
- return constructor.newInstance(null);
- }
- catch (InvocationTargetException e)
- {
- VMClass.throwException(e.getTargetException());
- throw (InternalError) new InternalError
- ("VMClass.throwException returned").initCause(e);
- }
- }
-
- /**
- * Discover whether an Object is an instance of this Class. Think of it
- * as almost like o instanceof (this class)
.
- *
- * @param o the Object to check
- * @return whether o is an instance of this class
* @since 1.1
*/
- public boolean isInstance(Object o)
- {
- return vmClass.isInstance (o);
- }
-
- /**
- * Discover whether an instance of the Class parameter would be an
- * instance of this Class as well. Think of doing
- * isInstance(c.newInstance())
or even
- * c.newInstance() instanceof (this class)
. 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);
- }
-
- /**
- * Check whether this class is an interface or not. Array types are not
- * interfaces.
- *
- * @return whether this class is an interface or not
- */
- public boolean isInterface()
- {
- return vmClass.isInterface ();
- }
-
- /**
- * Return whether this class is an array type.
- *
- * @return whether this class is an array type
- * @since 1.1
- */
- public boolean isArray()
- {
- int result = -1;
- if ((result = vmClass.isArray ()) < 0)
- return getName().charAt(0) == '[';
-
- return result == 1;
- }
-
- /**
- * Return whether this class is a primitive type. A primitive type class
- * is a class representing a kind of "placeholder" for the various
- * primitive types, or void. You can access the various primitive type
- * classes through java.lang.Boolean.TYPE, java.lang.Integer.TYPE, etc.,
- * or through boolean.class, int.class, etc.
- *
- * @return whether this class is a primitive type
- * @see Boolean#TYPE
- * @see Byte#TYPE
- * @see Character#TYPE
- * @see Short#TYPE
- * @see Integer#TYPE
- * @see Long#TYPE
- * @see Float#TYPE
- * @see Double#TYPE
- * @see Void#TYPE
- * @since 1.1
- */
- public boolean isPrimitive()
+ public Class[] getClasses()
{
- return vmClass.isPrimitive ();
+ memberAccessCheck(Member.PUBLIC);
+ return internalGetClasses();
}
/**
- * Get the name of this class, separated by dots for package separators.
- * Primitive types and arrays are encoded as:
- *
- * boolean Z - * byte B - * char C - * short S - * int I - * long J - * float F - * double D - * void V - * array type [element type - * class or interface, alone: <dotted name> - * class or interface, as element type: L<dotted name>; - * - * @return the name of this class + * LikegetClasses()
but without the security checks. */ - public String getName() + private Class[] internalGetClasses() { - return vmClass.getName (); + ArrayList list = new ArrayList(); + list.addAll(Arrays.asList(getDeclaredClasses(true))); + Class superClass = getSuperclass(); + if (superClass != null) + list.addAll(Arrays.asList(superClass.internalGetClasses())); + return (Class[])list.toArray(new Class[list.size()]); } /** @@ -422,115 +268,243 @@ } /** - * Get the direct superclass of this class. If this is an interface, - * Object, a primitive type, or void, it will return null. If this is an - * array type, it will return Object. + * If this is an array, get the Class representing the type of array. + * Examples: "[[Ljava.lang.String;" would return "[Ljava.lang.String;", and + * calling getComponentType on that would give "java.lang.String". If + * this is not an array, returns null. * - * @return the direct superclass of this class + * @return the array type of this class, or null + * @see Array + * @since 1.1 */ - public Class getSuperclass() + public Class getComponentType() { - return vmClass.getSuperclass (); + return vmClass.getComponentType (); } /** - * Returns thePackage
in which this class is defined - * Returns null when this information is not available from the - * classloader of this class or when the classloader of this class - * is null. + * Get a public constructor declared in this class. If the constructor takes + * no argument, an array of zero elements and null are equivalent for the + * types argument. A security check may be performed, with + *checkMemberAccess(this, Member.PUBLIC)
as well as + *checkPackageAccess
both having to succeed. * - * @return the package for this class, if it is available - * @since 1.2 + * @param types the type of each parameter + * @return the constructor + * @throws NoSuchMethodException if the constructor does not exist + * @throws SecurityException if the security check fails + * @see #getConstructors() + * @since 1.1 */ - public Package getPackage() + public Constructor getConstructor(Class[] args) throws NoSuchMethodException { - ClassLoader cl = getClassLoader(); - if (cl != null) - return cl.getPackage(getPackagePortion(getName())); - return null; + memberAccessCheck(Member.PUBLIC); + Constructor[] constructors = getDeclaredConstructors(true); + for (int i = 0; i < constructors.length; i++) + { + Constructor constructor = constructors[i]; + if (matchParameters(args, constructor.getParameterTypes())) + return constructor; + } + throw new NoSuchMethodException(); } /** - * Get the interfaces this class directly implements, in the - * order that they were declared. This returns an empty array, not null, - * for Object, primitives, void, and classes or interfaces with no direct - * superinterface. Array types return Cloneable and Serializable. + * Get all the public constructors of this class. This returns an array of + * length 0 if there are no constructors, including for primitive types, + * arrays, and interfaces. It does, however, include the default + * constructor if one was supplied by the compiler. A security check may + * be performed, withcheckMemberAccess(this, Member.PUBLIC)
+ * as well ascheckPackageAccess
both having to succeed. * - * @return the interfaces this class directly implements + * @return all public constructors in this class + * @throws SecurityException if the security check fails + * @since 1.1 */ - public Class[] getInterfaces() + public Constructor[] getConstructors() { - return vmClass.getInterfaces (); + memberAccessCheck(Member.PUBLIC); + return getDeclaredConstructors(true); } /** - * If this is an array, get the Class representing the type of array. - * Examples: "[[Ljava.lang.String;" would return "[Ljava.lang.String;", and - * calling getComponentType on that would give "java.lang.String". If - * this is not an array, returns null. + * Get a constructor declared in this class. If the constructor takes no + * argument, an array of zero elements and null are equivalent for the + * types argument. A security check may be performed, with + *checkMemberAccess(this, Member.DECLARED)
as well as + *checkPackageAccess
both having to succeed. * - * @return the array type of this class, or null - * @see Array + * @param types the type of each parameter + * @return the constructor + * @throws NoSuchMethodException if the constructor does not exist + * @throws SecurityException if the security check fails + * @see #getDeclaredConstructors() * @since 1.1 */ - public Class getComponentType() + public Constructor getDeclaredConstructor(Class[] args) + throws NoSuchMethodException { - return vmClass.getComponentType (); + memberAccessCheck(Member.DECLARED); + Constructor[] constructors = getDeclaredConstructors(false); + for (int i = 0; i < constructors.length; i++) + { + Constructor constructor = constructors[i]; + if (matchParameters(args, constructor.getParameterTypes())) + return constructor; + } + throw new NoSuchMethodException(); + } + + /** + * Get all the declared member classes and interfaces in this class, but + * not those inherited from superclasses. This returns an array of length + * 0 if there are no member classes, including for primitive types. A + * security check may be performed, with + *checkMemberAccess(this, Member.DECLARED)
as well as + *checkPackageAccess
both having to succeed. + * + * @return all declared member classes in this class + * @throws SecurityException if the security check fails + * @since 1.1 + */ + public Class[] getDeclaredClasses() + { + memberAccessCheck(Member.DECLARED); + return getDeclaredClasses(false); + } + + Class[] getDeclaredClasses (boolean publicOnly) + { + return vmClass.getDeclaredClasses (publicOnly); + } + + /** + * Get all the declared constructors of this class. This returns an array of + * length 0 if there are no constructors, including for primitive types, + * arrays, and interfaces. It does, however, include the default + * constructor if one was supplied by the compiler. A security check may + * be performed, withcheckMemberAccess(this, Member.DECLARED)
+ * as well ascheckPackageAccess
both having to succeed. + * + * @return all constructors in this class + * @throws SecurityException if the security check fails + * @since 1.1 + */ + public Constructor[] getDeclaredConstructors() + { + memberAccessCheck(Member.DECLARED); + return getDeclaredConstructors(false); + } + + Constructor[] getDeclaredConstructors (boolean publicOnly) + { + return vmClass.getDeclaredConstructors (publicOnly); + } + + /** + * Get a field declared in this class, where name is its simple name. The + * implicit length field of arrays is not available. A security check may + * be performed, withcheckMemberAccess(this, Member.DECLARED)
+ * as well ascheckPackageAccess
both having to succeed. + * + * @param name the name of the field + * @return the field + * @throws NoSuchFieldException if the field does not exist + * @throws SecurityException if the security check fails + * @see #getDeclaredFields() + * @since 1.1 + */ + public Field getDeclaredField(String name) throws NoSuchFieldException + { + memberAccessCheck(Member.DECLARED); + Field[] fields = getDeclaredFields(false); + for (int i = 0; i < fields.length; i++) + { + if (fields[i].getName().equals(name)) + return fields[i]; + } + throw new NoSuchFieldException(); } /** - * Get the modifiers of this class. These can be decoded using Modifier, - * and is limited to one of public, protected, or private, and any of - * final, static, abstract, or interface. An array class has the same - * public, protected, or private modifier as its component type, and is - * marked final but not an interface. Primitive types and void are marked - * public and final, but not an interface. + * Get all the declared fields in this class, but not those inherited from + * superclasses. This returns an array of length 0 if there are no fields, + * including for primitive types. This does not return the implicit length + * field of arrays. A security check may be performed, with + *checkMemberAccess(this, Member.DECLARED)
as well as + *checkPackageAccess
both having to succeed. * - * @return the modifiers of this class - * @see Modifer + * @return all declared fields in this class + * @throws SecurityException if the security check fails * @since 1.1 */ - public int getModifiers() + public Field[] getDeclaredFields() { - return vmClass.getModifiers (); + memberAccessCheck(Member.DECLARED); + return getDeclaredFields(false); + } + + Field[] getDeclaredFields (boolean publicOnly) + { + return vmClass.getDeclaredFields (publicOnly); } /** - * Get the signers of this class. This returns null if there are no signers, - * such as for primitive types or void. + * Get a method declared in this class, where name is its simple name. The + * implicit methods of Object are not available from arrays or interfaces. + * Constructors (named "" in the class file) and class initializers + * (name " ") are not available. The Virtual Machine allows + * multiple methods with the same signature but differing return types; in + * such a case the most specific return types are favored, then the final + * choice is arbitrary. If the method takes no argument, an array of zero + * elements and null are equivalent for the types argument. A security + * check may be performed, with + * checkMemberAccess(this, Member.DECLARED)
as well as + *checkPackageAccess
both having to succeed. * - * @return the signers of this class + * @param name the name of the method + * @param types the type of each parameter + * @return the method + * @throws NoSuchMethodException if the method does not exist + * @throws SecurityException if the security check fails + * @see #getDeclaredMethods() * @since 1.1 */ - public Object[] getSigners() + public Method getDeclaredMethod(String name, Class[] args) + throws NoSuchMethodException { - return signers == null ? null : (Object[]) signers.clone (); + memberAccessCheck(Member.DECLARED); + Method match = matchMethod(getDeclaredMethods(false), name, args); + if (match != null) + return match; + throw new NoSuchMethodException(); } /** - * Set the signers of this class. + * Get all the declared methods in this class, but not those inherited from + * superclasses. This returns an array of length 0 if there are no methods, + * including for primitive types. This does include the implicit methods of + * arrays and interfaces which mirror methods of Object, nor does it + * include constructors or the class initialization methods. The Virtual + * Machine allows multiple methods with the same signature but differing + * return types; all such methods are in the returned array. A security + * check may be performed, with + *checkMemberAccess(this, Member.DECLARED)
as well as + *checkPackageAccess
both having to succeed. * - * @param signers the signers of this class + * @return all declared methods in this class + * @throws SecurityException if the security check fails + * @since 1.1 */ - void setSigners(Object[] signers) + public Method[] getDeclaredMethods() { - this.signers = signers; + memberAccessCheck(Member.DECLARED); + return getDeclaredMethods(false); } - /** - * Perform security checks common to all of the methods that - * get members of this Class. - */ - private void memberAccessCheck(int which) - { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) + Method[] getDeclaredMethods (boolean publicOnly) { - sm.checkMemberAccess(this, which); - Package pkg = getPackage(); - if (pkg != null) - sm.checkPackageAccess(pkg.getName()); - } + return vmClass.getDeclaredMethods (publicOnly); } /** @@ -546,34 +520,27 @@ } /** - * Get all the public member classes and interfaces declared in this - * class or inherited from superclasses. This returns an array of length - * 0 if there are no member classes, including for primitive types. A - * security check may be performed, with + * Get a public field declared or inherited in this class, where name is + * its simple name. If the class contains multiple accessible fields by + * that name, an arbitrary one is returned. The implicit length field of + * arrays is not available. A security check may be performed, with *checkMemberAccess(this, Member.PUBLIC)
as well as *checkPackageAccess
both having to succeed. * - * @return all public member classes in this class + * @param name the name of the field + * @return the field + * @throws NoSuchFieldException if the field does not exist * @throws SecurityException if the security check fails + * @see #getFields() * @since 1.1 */ - public Class[] getClasses() + public Field getField(String name) throws NoSuchFieldException { memberAccessCheck(Member.PUBLIC); - return internalGetClasses(); - } - - /** - * LikegetClasses()
but without the security checks. - */ - private Class[] internalGetClasses() - { - ArrayList list = new ArrayList(); - list.addAll(Arrays.asList(getDeclaredClasses(true))); - Class superClass = getSuperclass(); - if (superClass != null) - list.addAll(Arrays.asList(superClass.internalGetClasses())); - return (Class[])list.toArray(new Class[list.size()]); + Field field = internalGetField(name); + if(field != null) + return field; + throw new NoSuchFieldException(); } /** @@ -611,62 +578,33 @@ } /** - * Get all the public methods declared in this class or inherited from - * superclasses. This returns an array of length 0 if there are no methods, - * including for primitive types. This does not include the implicit - * methods of interfaces which mirror methods of Object, nor does it - * include constructors or the class initialization methods. The Virtual - * Machine allows multiple methods with the same signature but differing - * return types; all such methods are in the returned array. A security - * check may be performed, with - *checkMemberAccess(this, Member.PUBLIC)
as well as - *checkPackageAccess
both having to succeed. + * Returns thePackage
in which this class is defined + * Returns null when this information is not available from the + * classloader of this class or when the classloader of this class + * is null. * - * @return all public methods in this class - * @throws SecurityException if the security check fails - * @since 1.1 + * @return the package for this class, if it is available + * @since 1.2 */ - public Method[] getMethods() + public Package getPackage() { - memberAccessCheck(Member.PUBLIC); - // NOTE the API docs claim that no methods are returned for arrays, - // but Sun's implementation *does* return the public methods of Object - // (as would be expected), so we follow their implementation instead - // of their documentation. - return internalGetMethods(); + ClassLoader cl = getClassLoader(); + if (cl != null) + return cl.getPackage(getPackagePortion(getName())); + return null; } /** - * LikegetMethods()
but without the security checks. + * Get the interfaces this class directly implements, in the + * order that they were declared. This returns an empty array, not null, + * for Object, primitives, void, and classes or interfaces with no direct + * superinterface. Array types return Cloneable and Serializable. + * + * @return the interfaces this class directly implements */ - private Method[] internalGetMethods() - { - HashMap map = new HashMap(); - Method[] methods; - Class[] interfaces = getInterfaces(); - for(int i = 0; i < interfaces.length; i++) - { - methods = interfaces[i].internalGetMethods(); - for(int j = 0; j < methods.length; j++) - { - map.put(new MethodKey(methods[j]), methods[j]); - } - } - Class superClass = getSuperclass(); - if(superClass != null) - { - methods = superClass.internalGetMethods(); - for(int i = 0; i < methods.length; i++) - { - map.put(new MethodKey(methods[i]), methods[i]); - } - } - methods = getDeclaredMethods(true); - for(int i = 0; i < methods.length; i++) + public Class[] getInterfaces() { - map.put(new MethodKey(methods[i]), methods[i]); - } - return (Method[])map.values().toArray(new Method[map.size()]); + return vmClass.getInterfaces (); } private static final class MethodKey @@ -702,84 +640,16 @@ return false; } } - return true; - } - } - return false; - } - - public int hashCode() - { - return hash; - } - } - - /** - * Get all the public constructors of this class. This returns an array of - * length 0 if there are no constructors, including for primitive types, - * arrays, and interfaces. It does, however, include the default - * constructor if one was supplied by the compiler. A security check may - * be performed, withcheckMemberAccess(this, Member.PUBLIC)
- * as well ascheckPackageAccess
both having to succeed. - * - * @return all public constructors in this class - * @throws SecurityException if the security check fails - * @since 1.1 - */ - public Constructor[] getConstructors() - { - memberAccessCheck(Member.PUBLIC); - return getDeclaredConstructors(true); - } - - /** - * Get a public field declared or inherited in this class, where name is - * its simple name. If the class contains multiple accessible fields by - * that name, an arbitrary one is returned. The implicit length field of - * arrays is not available. A security check may be performed, with - *checkMemberAccess(this, Member.PUBLIC)
as well as - *checkPackageAccess
both having to succeed. - * - * @param name the name of the field - * @return the field - * @throws NoSuchFieldException if the field does not exist - * @throws SecurityException if the security check fails - * @see #getFields() - * @since 1.1 - */ - public Field getField(String name) throws NoSuchFieldException - { - memberAccessCheck(Member.PUBLIC); - Field field = internalGetField(name); - if(field != null) - return field; - throw new NoSuchFieldException(); - } - - /** - * LikegetField(String)
but without the security checks and returns null - * instead of throwing NoSuchFieldException. - */ - private Field internalGetField(String name) - { - Field[] fields = getDeclaredFields(true); - for (int i = 0; i < fields.length; i++) - { - Field field = fields[i]; - if (field.getName().equals(name)) - return field; + return true; } - Class[] interfaces = getInterfaces(); - for (int i = 0; i < interfaces.length; i++) + } + return false; + } + + public int hashCode() { - Field field = interfaces[i].internalGetField(name); - if(field != null) - return field; + return hash; } - Class superClass = getSuperclass(); - if (superClass != null) - return superClass.internalGetField(name); - return null; } /** @@ -891,210 +761,132 @@ } /** - * Get a public constructor declared in this class. If the constructor takes - * no argument, an array of zero elements and null are equivalent for the - * types argument. A security check may be performed, with + * Get all the public methods declared in this class or inherited from + * superclasses. This returns an array of length 0 if there are no methods, + * including for primitive types. This does not include the implicit + * methods of interfaces which mirror methods of Object, nor does it + * include constructors or the class initialization methods. The Virtual + * Machine allows multiple methods with the same signature but differing + * return types; all such methods are in the returned array. A security + * check may be performed, with *checkMemberAccess(this, Member.PUBLIC)
as well as *checkPackageAccess
both having to succeed. * - * @param types the type of each parameter - * @return the constructor - * @throws NoSuchMethodException if the constructor does not exist + * @return all public methods in this class * @throws SecurityException if the security check fails - * @see #getConstructors() * @since 1.1 */ - public Constructor getConstructor(Class[] args) throws NoSuchMethodException + public Method[] getMethods() { memberAccessCheck(Member.PUBLIC); - Constructor[] constructors = getDeclaredConstructors(true); - for (int i = 0; i < constructors.length; i++) - { - Constructor constructor = constructors[i]; - if (matchParameters(args, constructor.getParameterTypes())) - return constructor; - } - throw new NoSuchMethodException(); + // NOTE the API docs claim that no methods are returned for arrays, + // but Sun's implementation *does* return the public methods of Object + // (as would be expected), so we follow their implementation instead + // of their documentation. + return internalGetMethods(); } /** - * Get all the declared member classes and interfaces in this class, but - * not those inherited from superclasses. This returns an array of length - * 0 if there are no member classes, including for primitive types. A - * security check may be performed, with - *checkMemberAccess(this, Member.DECLARED)
as well as - *checkPackageAccess
both having to succeed. - * - * @return all declared member classes in this class - * @throws SecurityException if the security check fails - * @since 1.1 + * LikegetMethods()
but without the security checks. */ - public Class[] getDeclaredClasses() + private Method[] internalGetMethods() { - memberAccessCheck(Member.DECLARED); - return getDeclaredClasses(false); - } - - Class[] getDeclaredClasses (boolean publicOnly) + HashMap map = new HashMap(); + Method[] methods; + Class[] interfaces = getInterfaces(); + for(int i = 0; i < interfaces.length; i++) { - return vmClass.getDeclaredClasses (publicOnly); - } - - /** - * Get all the declared fields in this class, but not those inherited from - * superclasses. This returns an array of length 0 if there are no fields, - * including for primitive types. This does not return the implicit length - * field of arrays. A security check may be performed, with - *checkMemberAccess(this, Member.DECLARED)
as well as - *checkPackageAccess
both having to succeed. - * - * @return all declared fields in this class - * @throws SecurityException if the security check fails - * @since 1.1 - */ - public Field[] getDeclaredFields() + methods = interfaces[i].internalGetMethods(); + for(int j = 0; j < methods.length; j++) { - memberAccessCheck(Member.DECLARED); - return getDeclaredFields(false); + map.put(new MethodKey(methods[j]), methods[j]); } - - Field[] getDeclaredFields (boolean publicOnly) - { - return vmClass.getDeclaredFields (publicOnly); } - - /** - * Get all the declared methods in this class, but not those inherited from - * superclasses. This returns an array of length 0 if there are no methods, - * including for primitive types. This does include the implicit methods of - * arrays and interfaces which mirror methods of Object, nor does it - * include constructors or the class initialization methods. The Virtual - * Machine allows multiple methods with the same signature but differing - * return types; all such methods are in the returned array. A security - * check may be performed, with - *checkMemberAccess(this, Member.DECLARED)
as well as - *checkPackageAccess
both having to succeed. - * - * @return all declared methods in this class - * @throws SecurityException if the security check fails - * @since 1.1 - */ - public Method[] getDeclaredMethods() + Class superClass = getSuperclass(); + if(superClass != null) { - memberAccessCheck(Member.DECLARED); - return getDeclaredMethods(false); - } - - Method[] getDeclaredMethods (boolean publicOnly) + methods = superClass.internalGetMethods(); + for(int i = 0; i < methods.length; i++) { - return vmClass.getDeclaredMethods (publicOnly); + map.put(new MethodKey(methods[i]), methods[i]); } - - /** - * Get all the declared constructors of this class. This returns an array of - * length 0 if there are no constructors, including for primitive types, - * arrays, and interfaces. It does, however, include the default - * constructor if one was supplied by the compiler. A security check may - * be performed, withcheckMemberAccess(this, Member.DECLARED)
- * as well ascheckPackageAccess
both having to succeed. - * - * @return all constructors in this class - * @throws SecurityException if the security check fails - * @since 1.1 - */ - public Constructor[] getDeclaredConstructors() - { - memberAccessCheck(Member.DECLARED); - return getDeclaredConstructors(false); } - - Constructor[] getDeclaredConstructors (boolean publicOnly) + methods = getDeclaredMethods(true); + for(int i = 0; i < methods.length; i++) { - return vmClass.getDeclaredConstructors (publicOnly); + map.put(new MethodKey(methods[i]), methods[i]); + } + return (Method[])map.values().toArray(new Method[map.size()]); } /** - * Get a field declared in this class, where name is its simple name. The - * implicit length field of arrays is not available. A security check may - * be performed, withcheckMemberAccess(this, Member.DECLARED)
- * as well ascheckPackageAccess
both having to succeed. + * Get the modifiers of this class. These can be decoded using Modifier, + * and is limited to one of public, protected, or private, and any of + * final, static, abstract, or interface. An array class has the same + * public, protected, or private modifier as its component type, and is + * marked final but not an interface. Primitive types and void are marked + * public and final, but not an interface. * - * @param name the name of the field - * @return the field - * @throws NoSuchFieldException if the field does not exist - * @throws SecurityException if the security check fails - * @see #getDeclaredFields() + * @return the modifiers of this class + * @see Modifer * @since 1.1 */ - public Field getDeclaredField(String name) throws NoSuchFieldException - { - memberAccessCheck(Member.DECLARED); - Field[] fields = getDeclaredFields(false); - for (int i = 0; i < fields.length; i++) + public int getModifiers() { - if (fields[i].getName().equals(name)) - return fields[i]; - } - throw new NoSuchFieldException(); + return vmClass.getModifiers (); } /** - * Get a method declared in this class, where name is its simple name. The - * implicit methods of Object are not available from arrays or interfaces. - * Constructors (named "" in the class file) and class initializers - * (name " ") are not available. The Virtual Machine allows - * multiple methods with the same signature but differing return types; in - * such a case the most specific return types are favored, then the final - * choice is arbitrary. If the method takes no argument, an array of zero - * elements and null are equivalent for the types argument. A security - * check may be performed, with - * checkMemberAccess(this, Member.DECLARED)
as well as - *checkPackageAccess
both having to succeed. + * Get the name of this class, separated by dots for package separators. + * Primitive types and arrays are encoded as: + *+ * boolean Z + * byte B + * char C + * short S + * int I + * long J + * float F + * double D + * void V + * array type [element type + * class or interface, alone: <dotted name> + * class or interface, as element type: L<dotted name>; * - * @param name the name of the method - * @param types the type of each parameter - * @return the method - * @throws NoSuchMethodException if the method does not exist - * @throws SecurityException if the security check fails - * @see #getDeclaredMethods() - * @since 1.1 + * @return the name of this class */ - public Method getDeclaredMethod(String name, Class[] args) - throws NoSuchMethodException + public String getName() { - memberAccessCheck(Member.DECLARED); - Method match = matchMethod(getDeclaredMethods(false), name, args); - if (match != null) - return match; - throw new NoSuchMethodException(); + return vmClass.getName (); } /** - * Get a constructor declared in this class. If the constructor takes no - * argument, an array of zero elements and null are equivalent for the - * types argument. A security check may be performed, with - *checkMemberAccess(this, Member.DECLARED)
as well as - *checkPackageAccess
both having to succeed. + * 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. * - * @param types the type of each parameter - * @return the constructor - * @throws NoSuchMethodException if the constructor does not exist - * @throws SecurityException if the security check fails - * @see #getDeclaredConstructors() + *If the name you supply is absolute (it starts with a
/
), + * then it is passed on to getResource() as is. If it is relative, the + * package name is prepended, and.
's are replaced with + */
. + * + *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 Constructor getDeclaredConstructor(Class[] args) - throws NoSuchMethodException - { - memberAccessCheck(Member.DECLARED); - Constructor[] constructors = getDeclaredConstructors(false); - for (int i = 0; i < constructors.length; i++) - { - Constructor constructor = constructors[i]; - if (matchParameters(args, constructor.getParameterTypes())) - return constructor; - } - throw new NoSuchMethodException(); + public URL getResource(String name) + { + if(name.length() > 0 && name.charAt(0) != '/') + name = getPackagePortion(getName()).replace('.','/') + + "/" + name; + ClassLoader c = getClassLoader(); + if (c == null) + return ClassLoader.getSystemResource(name); + return c.getResource(name); } /** @@ -1128,32 +920,198 @@ } /** - * 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. + * Get the signers of this class. This returns null if there are no signers, + * such as for primitive types or void. * - *
If the name you supply is absolute (it starts with a
/
), - * then it is passed on to getResource() as is. If it is relative, the - * package name is prepended, and.
's are replaced with - */
. + * @return the signers of this class + * @since 1.1 + */ + public Object[] getSigners() + { + return signers == null ? null : (Object[]) signers.clone (); + } + + /** + * Set the signers of this class. * - *The URL returned is system- and classloader-dependent, and could - * change across implementations. + * @param signers the signers of this class + */ + void setSigners(Object[] signers) + { + this.signers = signers; + } + + /** + * Get the direct superclass of this class. If this is an interface, + * Object, a primitive type, or void, it will return null. If this is an + * array type, it will return Object. * - * @param name the name of the resource, generally a path - * @return the URL to the resource - * @throws NullPointerException if name is null + * @return the direct superclass of this class + */ + public Class getSuperclass() + { + return vmClass.getSuperclass (); + } + + /** + * Return whether this class is an array type. + * + * @return whether this class is an array type * @since 1.1 */ - public URL getResource(String name) + public boolean isArray() { - if(name.length() > 0 && name.charAt(0) != '/') - name = getPackagePortion(getName()).replace('.','/') - + "/" + name; - ClassLoader c = getClassLoader(); - if (c == null) - return ClassLoader.getSystemResource(name); - return c.getResource(name); + int result = -1; + if ((result = vmClass.isArray ()) < 0) + return getName().charAt(0) == '['; + + return result == 1; + } + + /** + * Discover whether an instance of the Class parameter would be an + * instance of this Class as well. Think of doing + *
isInstance(c.newInstance())
or even + *c.newInstance() instanceof (this class)
. 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); + } + + /** + * Discover whether an Object is an instance of this Class. Think of it + * as almost likeo instanceof (this class)
. + * + * @param o the Object to check + * @return whether o is an instance of this class + * @since 1.1 + */ + public boolean isInstance(Object o) + { + return vmClass.isInstance (o); + } + + /** + * Check whether this class is an interface or not. Array types are not + * interfaces. + * + * @return whether this class is an interface or not + */ + public boolean isInterface() + { + return vmClass.isInterface (); + } + + /** + * Return whether this class is a primitive type. A primitive type class + * is a class representing a kind of "placeholder" for the various + * primitive types, or void. You can access the various primitive type + * classes through java.lang.Boolean.TYPE, java.lang.Integer.TYPE, etc., + * or through boolean.class, int.class, etc. + * + * @return whether this class is a primitive type + * @see Boolean#TYPE + * @see Byte#TYPE + * @see Character#TYPE + * @see Short#TYPE + * @see Integer#TYPE + * @see Long#TYPE + * @see Float#TYPE + * @see Double#TYPE + * @see Void#TYPE + * @since 1.1 + */ + public boolean isPrimitive() + { + return vmClass.isPrimitive (); + } + + /** + * Get a new instance of this class by calling the no-argument constructor. + * The class is initialized if it has not been already. A security check + * may be performed, withcheckMemberAccess(this, Member.PUBLIC)
+ * as well ascheckPackageAccess
both having to succeed. + * + * @return a new instance of this class + * @throws InstantiationException if there is not a no-arg constructor + * for this class, including interfaces, abstract classes, arrays, + * primitive types, and void; or if an exception occurred during + * the constructor + * @throws IllegalAccessException if you are not allowed to access the + * no-arg constructor because of scoping reasons + * @throws SecurityException if the security check fails + * @throws ExceptionInInitializerError if class initialization caused by + * this call fails with an exception + */ + public Object newInstance() + throws InstantiationException, IllegalAccessException + { + memberAccessCheck(Member.PUBLIC); + Constructor constructor; + synchronized(this) + { + constructor = this.constructor; + } + if (constructor == null) + { + Constructor[] constructors = getDeclaredConstructors(false); + for (int i = 0; i < constructors.length; i++) + { + if (constructors[i].getParameterTypes().length == 0) + { + constructor = constructors[i]; + break; + } + } + if (constructor == null) + throw new InstantiationException(getName()); + if (!Modifier.isPublic(constructor.getModifiers())) + { + final Constructor finalConstructor = constructor; + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + finalConstructor.setAccessible(true); + return null; + } + }); + } + synchronized(this) + { + if (this.constructor == null) + this.constructor = constructor; + } + } + int modifiers = constructor.getModifiers(); + if (!Modifier.isPublic(modifiers)) + { + Class caller = VMSecurityManager.getClassContext()[1]; + if (caller != this && + (Modifier.isPrivate(modifiers) + || getClassLoader() != caller.getClassLoader() + || !getPackagePortion(getName()) + .equals(getPackagePortion(caller.getName())))) + throw new IllegalAccessException(getName() + + " has an inaccessible constructor"); + } + try + { + return constructor.newInstance(null); + } + catch (InvocationTargetException e) + { + VMClass.throwException(e.getTargetException()); + throw (InternalError) new InternalError + ("VMClass.throwException returned").initCause(e); + } } /** @@ -1259,6 +1217,48 @@ return status.equals(Boolean.TRUE); } return c.defaultAssertionStatus; + } + + /** + * LikegetField(String)
but without the security checks and returns null + * instead of throwing NoSuchFieldException. + */ + private Field internalGetField(String name) + { + Field[] fields = getDeclaredFields(true); + for (int i = 0; i < fields.length; i++) + { + Field field = fields[i]; + if (field.getName().equals(name)) + return field; + } + Class[] interfaces = getInterfaces(); + for (int i = 0; i < interfaces.length; i++) + { + Field field = interfaces[i].internalGetField(name); + if(field != null) + return field; + } + Class superClass = getSuperclass(); + if (superClass != null) + return superClass.internalGetField(name); + return null; + } + + /** + * Perform security checks common to all of the methods that + * get members of this Class. + */ + private void memberAccessCheck(int which) + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + { + sm.checkMemberAccess(this, which); + Package pkg = getPackage(); + if (pkg != null) + sm.checkPackageAccess(pkg.getName()); + } } /**