summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorAndrew John Hughes <gnu_andrew@member.fsf.org>2006-04-03 20:09:13 +0000
committerAndrew John Hughes <gnu_andrew@member.fsf.org>2006-04-03 20:09:13 +0000
commit2a8df925bcd276fa213b64d1fca0cf4a52c4040d (patch)
tree3bbb67d6bbc77ccaf38bb627c179bf14f3f2554b /java
parent3f864b39e567ca569021118e754891eb1956610c (diff)
downloadclasspath-2a8df925bcd276fa213b64d1fca0cf4a52c4040d.tar.gz
2006-04-03 Andrew John Hughes <gnu_andrew@member.fsf.org>
* gnu/java/lang/reflect/ClassSignatureParser.java, * gnu/java/lang/reflect/FieldSignatureParser.java, * gnu/java/lang/reflect/GenericSignatureParser.java, * gnu/java/lang/reflect/MethodSignatureParser.java, * gnu/java/lang/reflect/TypeImpl.java, * java/lang/Class.java, * java/lang/reflect/GenericDeclaration.java, * java/lang/reflect/MalformedParameterizedTypeException.java, * java/lang/reflect/TypeVariable.java, * java/util/Arrays.java, * vm/reference/java/lang/VMClass.java, * vm/reference/java/lang/reflect/Constructor.java, * vm/reference/java/lang/reflect/Method.java: Incorporate changes from the generics branch. 2005-10-01 Jeroen Frijters <jeroen@frijters.net> * vm/reference/java/lang/reflect/Constructor.java (getSignature): New method. (getGenericExceptionTypes): New method. (getGenericParameterTypes): New method. * vm/reference/java/lang/reflect/Method.java (getSignature): New method. (getGenericExceptionTypes): New method. (getGenericParameterTypes): New method. (getGenericReturnType): New method. 2005-09-30 Jeroen Frijters <jeroen@frijters.net> * gnu/java/lang/reflect/FieldSignatureParser.java: New file. * gnu/java/lang/reflect/ClassSignatureParser.java, gnu/java/lang/reflect/GenericSignatureParser.java, gnu/java/lang/reflect/MethodSignatureParser.java: Finished implementation. 2005-09-25 Jeroen Frijters <jeroen@frijters.net> * gnu/java/lang/reflect/ClassSignatureParser.java, gnu/java/lang/reflect/GenericSignatureParser.java, gnu/java/lang/reflect/MethodSignatureParser.java: New files. * java/lang/Class.java (getGenericInterfaces, getGenericSuperclass, getTypeParameters): Implemented. * vm/reference/java/lang/VMClass.java (getSimpleName, getDeclaredAnnotations, getCanonicalName, getEnclosingClass, getEnclosingConstructor, getEnclosingMethod, isAnonymousClass, isLocalClass, isMemberClass): Removed generic types from signatures. (getGenericInterfaces, getGenericSuperclass, getTypeParameters): Removed. (getClassSignature): New method. * vm/reference/java/lang/reflect/Constructor.java (getTypeParameters): Implemented. * vm/reference/java/lang/reflect/Method.java (getTypeParameters, getSignature): New methods. 2005-06-09 Andrew John Hughes <gnu_andrew@member.fsf.org> * java/lang/Class.java: (asSubclass(Class)): Documented. (getCanonicalName()): Implemented. (getEnclosingClass()): Implemented. (getEnclosingConstructor()): Implemented. (getEnclosingMethod()): Implemented. (getGenericInterfaces()): Implemented. (getGenericSuperclass()): Implemented. (getTypeParameters()): Implemented. (isAnonymousClass()): Implemented. (isLocalClass()): Implemented. (isMemberClass()): Implemented. * vm/reference/java/lang/VMClass.java: (getSuperClass(Class<?>)): Updated return type. (getSimpleName(Class<?>)): Use VM methods directly. (getCanonicalName(Class<?>)): Implemented. (getEnclosingClass(Class<?>)): New native method. (getEnclosingConstructor(Class<?>)): New native method. (getEnclosingMethod(Class<?>)): New native method. (getGenericInterfaces(Class<?>)): New native method. (getGenericSuperclass(Class<?>)): New native method. (getTypeParameters(Class<T>)): New native method. (isAnonymousClass(Class<?>)): New native method. (isLocalClass(Class<?>)): New native method. (isMemberClass(Class<?>)): New native method. * vm/reference/java/lang/reflect/Constructor.java: (getTypeParameters()): Changed to native method. 2005-05-05 Andrew John Hughes <gnu_andrew@member.fsf.org> * java/lang/Class.java: (getSimpleName()): Implemented. * vm/reference/java/lang/VMClass.java: (getSimpleName()): Reference implementation. 2005-04-20 Tom Tromey <tromey@redhat.com> * java/util/Arrays.java (hashCode): New methods. (deepHashCode): New method. (deepEquals): Likewise. (toString): New methods. (deepToString): New method. 2005-04-04 Andrew John Hughes <gnu_andrew@member.fsf.org> * java/lang/Class.java: (isEnum()): New method implemented. (isSynthetic()): New method implemented. (isAnnotation()): New method implemented. * vm/reference/java/lang/VMClass.java: (isEnum()): New native method. (isSynthetic()): New native method. (isAnnotation()): New native method. 2005-03-21 Andrew John Hughes <gnu_andrew@member.fsf.org> * java/lang/Class.java: Implements java.lang.reflect.Type
Diffstat (limited to 'java')
-rw-r--r--java/lang/Class.java340
-rw-r--r--java/lang/reflect/GenericDeclaration.java63
-rw-r--r--java/lang/reflect/MalformedParameterizedTypeException.java58
-rw-r--r--java/lang/reflect/TypeVariable.java99
-rw-r--r--java/util/Arrays.java557
5 files changed, 1019 insertions, 98 deletions
diff --git a/java/lang/Class.java b/java/lang/Class.java
index c4235e680..c2460736d 100644
--- a/java/lang/Class.java
+++ b/java/lang/Class.java
@@ -39,17 +39,19 @@ exception statement from your version. */
package java.lang;
import gnu.classpath.VMStackWalker;
+import gnu.java.lang.reflect.ClassSignatureParser;
import java.io.InputStream;
-import java.io.ObjectStreamClass;
import java.io.Serializable;
-import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
+import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
import java.net.URL;
import java.security.AccessController;
import java.security.AllPermission;
@@ -87,11 +89,14 @@ import java.util.HashSet;
*
* @author John Keiser
* @author Eric Blake (ebb9@email.byu.edu)
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
* @author Tom Tromey (tromey@cygnus.com)
* @since 1.0
* @see ClassLoader
*/
-public final class Class implements Serializable
+public final class Class
+ implements Serializable, Type, GenericDeclaration
{
/**
* Compatible with JDK 1.0+.
@@ -1251,9 +1256,46 @@ public final class Class implements Serializable
return c.defaultAssertionStatus;
}
+ /*
+ * <p>
+ * Casts this class to represent a subclass of the specified class.
+ * This method is useful for `narrowing' the type of a class so that
+ * the class object, and instances of that class, can match the contract
+ * of a more restrictive method. For example, if this class has the
+ * static type of <code>Class&lt;Object&gt;</code>, and a dynamic type of
+ * <code>Class&lt;Rectangle&gt;</code>, then, assuming <code>Shape</code> is
+ * a superclass of <code>Rectangle</code>, this method can be used on
+ * this class with the parameter, <code>Class&lt;Shape&gt;</code>, to retain
+ * the same instance but with the type
+ * <code>Class&lt;? extends Shape&gt;</code>.
+ * </p>
+ * <p>
+ * If this class can be converted to an instance which is parameterised
+ * over a subtype of the supplied type, <code>U</code>, then this method
+ * returns an appropriately cast reference to this object. Otherwise,
+ * a <code>ClassCastException</code> is thrown.
+ * </p>
+ *
+ * @param klass the class object, the parameterized type (<code>U</code>) of
+ * which should be a superclass of the parameterized type of
+ * this instance.
+ * @return a reference to this object, appropriately cast.
+ * @throws ClassCastException if this class can not be converted to one
+ * which represents a subclass of the specified
+ * type, <code>U</code>.
+ * @since 1.5
+ */
+ /* FIXME[GENERICS]: Should be <U> Class<? extends U> asSubClass(Class<U> klass */
+ public Class asSubclass(Class klass)
+ {
+ if (! klass.isAssignableFrom(this))
+ throw new ClassCastException();
+ return this; /* FIXME[GENERICS]: Should cast to Class<? extends U> */
+ }
+
/**
- * Like <code>getField(String)</code> but without the security checks and returns null
- * instead of throwing NoSuchFieldException.
+ * Like <code>getField(String)</code> but without the security checks and
+ * returns null instead of throwing NoSuchFieldException.
*/
private Field internalGetField(String name)
{
@@ -1306,4 +1348,292 @@ public final class Class implements Serializable
sm.checkPackageAccess(pkg.getName());
}
}
+
+ /**
+ * Returns true if this class is an <code>Enum</code>.
+ *
+ * @return true if this is an enumeration class.
+ * @since 1.5
+ */
+ public boolean isEnum()
+ {
+ return VMClass.isEnum(this);
+ }
+
+ /**
+ * Returns true if this class is a synthetic class, generated by
+ * the compiler.
+ *
+ * @return true if this is a synthetic class.
+ * @since 1.5
+ */
+ public boolean isSynthetic()
+ {
+ return VMClass.isSynthetic(this);
+ }
+
+ /**
+ * Returns true if this class is an <code>Annotation</code>.
+ *
+ * @return true if this is an annotation class.
+ * @since 1.5
+ */
+ public boolean isAnnotation()
+ {
+ return VMClass.isAnnotation(this);
+ }
+
+ /**
+ * Returns the simple name for this class, as used in the source
+ * code. For normal classes, this is the content returned by
+ * <code>getName()</code> which follows the last ".". Anonymous
+ * classes have no name, and so the result of calling this method is
+ * "". The simple name of an array consists of the simple name of
+ * its component type, followed by "[]". Thus, an array with the
+ * component type of an anonymous class has a simple name of simply
+ * "[]".
+ *
+ * @return the simple name for this class.
+ * @since 1.5
+ */
+ public String getSimpleName()
+ {
+ return VMClass.getSimpleName(this);
+ }
+
+ /**
+ * <p>
+ * Returns the canonical name of this class, as defined by section
+ * 6.7 of the Java language specification. Each package, top-level class,
+ * top-level interface and primitive type has a canonical name. A member
+ * class has a canonical name, if its parent class has one. Likewise,
+ * an array type has a canonical name, if its component type does.
+ * Local or anonymous classes do not have canonical names.
+ * </p>
+ * <p>
+ * The canonical name for top-level classes, top-level interfaces and
+ * primitive types is always the same as the fully-qualified name.
+ * For array types, the canonical name is the canonical name of its
+ * component type with `[]' appended.
+ * </p>
+ * <p>
+ * The canonical name of a member class always refers to the place where
+ * the class was defined, and is composed of the canonical name of the
+ * defining class and the simple name of the member class, joined by `.'.
+ * For example, if a <code>Person</code> class has an inner class,
+ * <code>M</code>, then both its fully-qualified name and canonical name
+ * is <code>Person.M</code>. A subclass, <code>Staff</code>, of
+ * <code>Person</code> refers to the same inner class by the fully-qualified
+ * name of <code>Staff.M</code>, but its canonical name is still
+ * <code>Person.M</code>.
+ * </p>
+ * <p>
+ * Where no canonical name is present, <code>null</code> is returned.
+ * </p>
+ *
+ * @return the canonical name of the class, or <code>null</code> if the
+ * class doesn't have a canonical name.
+ * @since 1.5
+ */
+ public String getCanonicalName()
+ {
+ return VMClass.getCanonicalName(this);
+ }
+
+ /**
+ * Returns the class which immediately encloses this class. If this class
+ * is a top-level class, this method returns <code>null</code>.
+ *
+ * @return the immediate enclosing class, or <code>null</code> if this is
+ * a top-level class.
+ * @since 1.5
+ */
+ /* FIXME[GENERICS]: Should return Class<?> */
+ public Class getEnclosingClass()
+ {
+ return VMClass.getEnclosingClass(this);
+ }
+
+ /**
+ * Returns the constructor which immediately encloses this class. If
+ * this class is a top-level class, or a local or anonymous class
+ * immediately enclosed by a type definition, instance initializer
+ * or static initializer, then <code>null</code> is returned.
+ *
+ * @return the immediate enclosing constructor if this class is
+ * declared within a constructor. Otherwise, <code>null</code>
+ * is returned.
+ * @since 1.5
+ */
+ /* FIXME[GENERICS]: Should return Constructor<?> */
+ public Constructor getEnclosingConstructor()
+ {
+ return VMClass.getEnclosingConstructor(this);
+ }
+
+ /**
+ * Returns the method which immediately encloses this class. If
+ * this class is a top-level class, or a local or anonymous class
+ * immediately enclosed by a type definition, instance initializer
+ * or static initializer, then <code>null</code> is returned.
+ *
+ * @return the immediate enclosing method if this class is
+ * declared within a method. Otherwise, <code>null</code>
+ * is returned.
+ * @since 1.5
+ */
+ public Method getEnclosingMethod()
+ {
+ return VMClass.getEnclosingMethod(this);
+ }
+
+ /**
+ * <p>
+ * Returns an array of <code>Type</code> objects which represent the
+ * interfaces directly implemented by this class or extended by this
+ * interface.
+ * </p>
+ * <p>
+ * If one of the superinterfaces is a parameterized type, then the
+ * object returned for this interface reflects the actual type
+ * parameters used in the source code. Type parameters are created
+ * using the semantics specified by the <code>ParameterizedType</code>
+ * interface, and only if an instance has not already been created.
+ * </p>
+ * <p>
+ * The order of the interfaces in the array matches the order in which
+ * the interfaces are declared. For classes which represent an array,
+ * an array of two interfaces, <code>Cloneable</code> and
+ * <code>Serializable</code>, is always returned, with the objects in
+ * that order. A class representing a primitive type or void always
+ * returns an array of zero size.
+ * </p>
+ *
+ * @return an array of interfaces implemented or extended by this class.
+ * @throws GenericSignatureFormatError if the generic signature of one
+ * of the interfaces does not comply with that specified by the Java
+ * Virtual Machine specification, 3rd edition.
+ * @throws TypeNotPresentException if any of the superinterfaces refers
+ * to a non-existant type.
+ * @throws MalformedParameterizedTypeException if any of the interfaces
+ * refer to a parameterized type that can not be instantiated for
+ * some reason.
+ * @since 1.5
+ * @see java.lang.reflect.ParameterizedType
+ */
+ public Type[] getGenericInterfaces()
+ {
+ if (isPrimitive())
+ return new Type[0];
+
+ String sig = VMClass.getClassSignature(this);
+ if (sig == null)
+ return getInterfaces();
+
+ ClassSignatureParser p = new ClassSignatureParser(this, sig);
+ return p.getInterfaceTypes();
+ }
+
+ /**
+ * <p>
+ * Returns a <code>Type</code> object representing the direct superclass,
+ * whether class, interface, primitive type or void, of this class.
+ * If this class is an array class, then a class instance representing
+ * the <code>Object</code> class is returned. If this class is primitive,
+ * an interface, or a representation of either the <code>Object</code>
+ * class or void, then <code>null</code> is returned.
+ * </p>
+ * <p>
+ * If the superclass is a parameterized type, then the
+ * object returned for this interface reflects the actual type
+ * parameters used in the source code. Type parameters are created
+ * using the semantics specified by the <code>ParameterizedType</code>
+ * interface, and only if an instance has not already been created.
+ * </p>
+ *
+ * @return the superclass of this class.
+ * @throws GenericSignatureFormatError if the generic signature of the
+ * class does not comply with that specified by the Java
+ * Virtual Machine specification, 3rd edition.
+ * @throws TypeNotPresentException if the superclass refers
+ * to a non-existant type.
+ * @throws MalformedParameterizedTypeException if the superclass
+ * refers to a parameterized type that can not be instantiated for
+ * some reason.
+ * @since 1.5
+ * @see java.lang.reflect.ParameterizedType
+ */
+ public Type getGenericSuperclass()
+ {
+ if (isArray())
+ return Object.class;
+
+ if (isPrimitive() || isInterface() || this == Object.class)
+ return null;
+
+ String sig = VMClass.getClassSignature(this);
+ if (sig == null)
+ return getSuperclass();
+
+ ClassSignatureParser p = new ClassSignatureParser(this, sig);
+ return p.getSuperclassType();
+ }
+
+ /**
+ * Returns an array of <code>TypeVariable</code> objects that represents
+ * the type variables declared by this class, in declaration order.
+ * An array of size zero is returned if this class has no type
+ * variables.
+ *
+ * @return the type variables associated with this class.
+ * @throws GenericSignatureFormatError if the generic signature does
+ * not conform to the format specified in the Virtual Machine
+ * specification, version 3.
+ * @since 1.5
+ */
+ /* FIXME[GENERICS]: Should return TypeVariable<Class<T>> */
+ public TypeVariable[] getTypeParameters()
+ {
+ String sig = VMClass.getClassSignature(this);
+ if (sig == null)
+ return new TypeVariable[0];
+
+ ClassSignatureParser p = new ClassSignatureParser(this, sig);
+ return p.getTypeParameters();
+ }
+
+ /**
+ * Returns true if this object represents an anonymous class.
+ *
+ * @return true if this object represents an anonymous class.
+ * @since 1.5
+ */
+ public boolean isAnonymousClass()
+ {
+ return VMClass.isAnonymousClass(this);
+ }
+
+ /**
+ * Returns true if this object represents an local class.
+ *
+ * @return true if this object represents an local class.
+ * @since 1.5
+ */
+ public boolean isLocalClass()
+ {
+ return VMClass.isLocalClass(this);
+ }
+
+ /**
+ * Returns true if this object represents an member class.
+ *
+ * @return true if this object represents an member class.
+ * @since 1.5
+ */
+ public boolean isMemberClass()
+ {
+ return VMClass.isMemberClass(this);
+ }
+
+
}
diff --git a/java/lang/reflect/GenericDeclaration.java b/java/lang/reflect/GenericDeclaration.java
new file mode 100644
index 000000000..14f5ba832
--- /dev/null
+++ b/java/lang/reflect/GenericDeclaration.java
@@ -0,0 +1,63 @@
+/* GenericDeclaration.java
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+/**
+ * Represents an entity that declares one or more type parameters.
+ * This includes classes and methods (including constructors).
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public interface GenericDeclaration
+{
+ /**
+ * Returns a <code>TypeVariable</code> object for each type variable
+ * declared by this entity, in order of declaration. An empty array
+ * is returned if no type variables are declared.
+ *
+ * @return an array of <code>TypeVariable</code> objects.
+ * @throws GenericSignatureFormatError if the signature format within the
+ * class file does not conform to that specified in the 3rd edition
+ * of the Java Virtual Machine Specification.
+ */
+ /* FIXME[GENERICS]: Should be TypeVariable<?>[] */
+ TypeVariable[] getTypeParameters();
+}
diff --git a/java/lang/reflect/MalformedParameterizedTypeException.java b/java/lang/reflect/MalformedParameterizedTypeException.java
new file mode 100644
index 000000000..f33c77820
--- /dev/null
+++ b/java/lang/reflect/MalformedParameterizedTypeException.java
@@ -0,0 +1,58 @@
+/* MalformedParameterizedTypeException.java
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+/**
+ * This exception class is thrown when one of the reflection
+ * methods encountered an invalid parameterized type within
+ * the metadata of a class. One possible reason for this
+ * exception being thrown is the specification of too few or
+ * too many type variables.
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class MalformedParameterizedTypeException
+ extends RuntimeException
+{
+ public MalformedParameterizedTypeException()
+ {
+ }
+}
diff --git a/java/lang/reflect/TypeVariable.java b/java/lang/reflect/TypeVariable.java
new file mode 100644
index 000000000..4ecc20c9d
--- /dev/null
+++ b/java/lang/reflect/TypeVariable.java
@@ -0,0 +1,99 @@
+/* TypeVariable.java
+ Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.lang.reflect;
+
+/**
+ * <p>
+ * This is a common interface for all type variables provided by
+ * the Java language. Instances are created the first time a type
+ * variable is needed by one of the reflective methods declared in
+ * this package.
+ * </p>
+ * <p>
+ * Creating a type variable requires resolving the appropriate type.
+ * This may involve resolving other classes as a side effect (e.g.
+ * if the type is nested inside other classes). Creation should not
+ * involve resolving the bounds. Repeated creation has no effect; an
+ * equivalent instance is returned. Caching is not required, but all
+ * instances must be <code>equal()</code> to each other.
+ * </p>
+ *
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+/* FIXME[GENERICS]: Should be TypeVariable<T extends GenericDeclaration> */
+public interface TypeVariable
+ extends Type
+{
+
+ /**
+ * Returns an array of <code>Type</code> objects which represent the upper
+ * bounds of this type variable. There is always a default bound of
+ * <code>Object</code>. Any <code>ParameterizedType</code>s will be
+ * created as necessary, and other types resolved.
+ *
+ * @return an array of <code>Type</code> objects representing the upper
+ * bounds.
+ * @throws TypeNotPresentException if any of the bounds refer to a
+ * non-existant type.
+ * @throws MalformedParameterizedTypeException if the creation of a
+ * <code>ParameterizedType</code> fails.
+ */
+ Type[] getBounds();
+
+
+ /**
+ * Returns a representation of the declaration used to declare this
+ * type variable.
+ *
+ * @return the <code>GenericDeclaration</code> object for this type
+ * variable.
+ */
+ /* FIXME[GENERICS]: Should return type T */
+ GenericDeclaration getGenericDeclaration();
+
+ /**
+ * Returns the name of the type variable, as written in the source
+ * code.
+ *
+ * @return the name of the type variable.
+ */
+ String getName();
+}
diff --git a/java/util/Arrays.java b/java/util/Arrays.java
index b28c156b4..b934591fd 100644
--- a/java/util/Arrays.java
+++ b/java/util/Arrays.java
@@ -2352,6 +2352,305 @@ public class Arrays
return new Arrays.ArrayList(a);
}
+ /**
+ * Returns the hashcode of an array of long numbers. If two arrays
+ * are equal, according to <code>equals()</code>, they should have the
+ * same hashcode. The hashcode returned by the method is equal to that
+ * obtained by the corresponding <code>List</code> object. This has the same
+ * data, but represents longs in their wrapper class, <code>Long</code>.
+ * For <code>null</code>, 0 is returned.
+ *
+ * @param v an array of long numbers for which the hash code should be
+ * computed.
+ * @return the hash code of the array, or 0 if null was given.
+ * @since 1.5
+ */
+ public static int hashCode(long[] v)
+ {
+ if (v == null)
+ return 0;
+ int result = 1;
+ for (int i = 0; i < v.length; ++i)
+ {
+ int elt = (int) (v[i] ^ (v[i] >>> 32));
+ result = 31 * result + elt;
+ }
+ return result;
+ }
+
+ /**
+ * Returns the hashcode of an array of integer numbers. If two arrays
+ * are equal, according to <code>equals()</code>, they should have the
+ * same hashcode. The hashcode returned by the method is equal to that
+ * obtained by the corresponding <code>List</code> object. This has the same
+ * data, but represents ints in their wrapper class, <code>Integer</code>.
+ * For <code>null</code>, 0 is returned.
+ *
+ * @param v an array of integer numbers for which the hash code should be
+ * computed.
+ * @return the hash code of the array, or 0 if null was given.
+ * @since 1.5
+ */
+ public static int hashCode(int[] v)
+ {
+ if (v == null)
+ return 0;
+ int result = 1;
+ for (int i = 0; i < v.length; ++i)
+ result = 31 * result + v[i];
+ return result;
+ }
+
+ /**
+ * Returns the hashcode of an array of short numbers. If two arrays
+ * are equal, according to <code>equals()</code>, they should have the
+ * same hashcode. The hashcode returned by the method is equal to that
+ * obtained by the corresponding <code>List</code> object. This has the same
+ * data, but represents shorts in their wrapper class, <code>Short</code>.
+ * For <code>null</code>, 0 is returned.
+ *
+ * @param v an array of short numbers for which the hash code should be
+ * computed.
+ * @return the hash code of the array, or 0 if null was given.
+ * @since 1.5
+ */
+ public static int hashCode(short[] v)
+ {
+ if (v == null)
+ return 0;
+ int result = 1;
+ for (int i = 0; i < v.length; ++i)
+ result = 31 * result + v[i];
+ return result;
+ }
+
+ /**
+ * Returns the hashcode of an array of characters. If two arrays
+ * are equal, according to <code>equals()</code>, they should have the
+ * same hashcode. The hashcode returned by the method is equal to that
+ * obtained by the corresponding <code>List</code> object. This has the same
+ * data, but represents chars in their wrapper class, <code>Character</code>.
+ * For <code>null</code>, 0 is returned.
+ *
+ * @param v an array of characters for which the hash code should be
+ * computed.
+ * @return the hash code of the array, or 0 if null was given.
+ * @since 1.5
+ */
+ public static int hashCode(char[] v)
+ {
+ if (v == null)
+ return 0;
+ int result = 1;
+ for (int i = 0; i < v.length; ++i)
+ result = 31 * result + v[i];
+ return result;
+ }
+
+ /**
+ * Returns the hashcode of an array of bytes. If two arrays
+ * are equal, according to <code>equals()</code>, they should have the
+ * same hashcode. The hashcode returned by the method is equal to that
+ * obtained by the corresponding <code>List</code> object. This has the same
+ * data, but represents bytes in their wrapper class, <code>Byte</code>.
+ * For <code>null</code>, 0 is returned.
+ *
+ * @param v an array of bytes for which the hash code should be
+ * computed.
+ * @return the hash code of the array, or 0 if null was given.
+ * @since 1.5
+ */
+ public static int hashCode(byte[] v)
+ {
+ if (v == null)
+ return 0;
+ int result = 1;
+ for (int i = 0; i < v.length; ++i)
+ result = 31 * result + v[i];
+ return result;
+ }
+
+ /**
+ * Returns the hashcode of an array of booleans. If two arrays
+ * are equal, according to <code>equals()</code>, they should have the
+ * same hashcode. The hashcode returned by the method is equal to that
+ * obtained by the corresponding <code>List</code> object. This has the same
+ * data, but represents booleans in their wrapper class,
+ * <code>Boolean</code>. For <code>null</code>, 0 is returned.
+ *
+ * @param v an array of booleans for which the hash code should be
+ * computed.
+ * @return the hash code of the array, or 0 if null was given.
+ * @since 1.5
+ */
+ public static int hashCode(boolean[] v)
+ {
+ if (v == null)
+ return 0;
+ int result = 1;
+ for (int i = 0; i < v.length; ++i)
+ result = 31 * result + (v[i] ? 1231 : 1237);
+ return result;
+ }
+
+ /**
+ * Returns the hashcode of an array of floats. If two arrays
+ * are equal, according to <code>equals()</code>, they should have the
+ * same hashcode. The hashcode returned by the method is equal to that
+ * obtained by the corresponding <code>List</code> object. This has the same
+ * data, but represents floats in their wrapper class, <code>Float</code>.
+ * For <code>null</code>, 0 is returned.
+ *
+ * @param v an array of floats for which the hash code should be
+ * computed.
+ * @return the hash code of the array, or 0 if null was given.
+ * @since 1.5
+ */
+ public static int hashCode(float[] v)
+ {
+ if (v == null)
+ return 0;
+ int result = 1;
+ for (int i = 0; i < v.length; ++i)
+ result = 31 * result + Float.floatToIntBits(v[i]);
+ return result;
+ }
+
+ /**
+ * Returns the hashcode of an array of doubles. If two arrays
+ * are equal, according to <code>equals()</code>, they should have the
+ * same hashcode. The hashcode returned by the method is equal to that
+ * obtained by the corresponding <code>List</code> object. This has the same
+ * data, but represents doubles in their wrapper class, <code>Double</code>.
+ * For <code>null</code>, 0 is returned.
+ *
+ * @param v an array of doubles for which the hash code should be
+ * computed.
+ * @return the hash code of the array, or 0 if null was given.
+ * @since 1.5
+ */
+ public static int hashCode(double[] v)
+ {
+ if (v == null)
+ return 0;
+ int result = 1;
+ for (int i = 0; i < v.length; ++i)
+ {
+ long l = Double.doubleToLongBits(v[i]);
+ int elt = (int) (l ^ (l >>> 32));
+ result = 31 * result + elt;
+ }
+ return result;
+ }
+
+ /**
+ * Returns the hashcode of an array of integer numbers. If two arrays
+ * are equal, according to <code>equals()</code>, they should have the
+ * same hashcode. The hashcode returned by the method is equal to that
+ * obtained by the corresponding <code>List</code> object. This has the same
+ * data, but represents ints in their wrapper class, <code>Integer</code>.
+ * For <code>null</code>, 0 is returned.
+ *
+ * @param v an array of integer numbers for which the hash code should be
+ * computed.
+ * @return the hash code of the array, or 0 if null was given.
+ * @since 1.5
+ */
+ public static int hashCode(Object[] v)
+ {
+ if (v == null)
+ return 0;
+ int result = 1;
+ for (int i = 0; i < v.length; ++i)
+ {
+ int elt = v[i] == null ? 0 : v[i].hashCode();
+ result = 31 * result + elt;
+ }
+ return result;
+ }
+
+ /** @since 1.5 */
+ public static int deepHashCode(Object[] v)
+ {
+ if (v == null)
+ return 0;
+ int result = 1;
+ for (int i = 0; i < v.length; ++i)
+ {
+ int elt;
+ if (v[i] == null)
+ elt = 0;
+ else if (v[i] instanceof boolean[])
+ elt = hashCode((boolean[]) v[i]);
+ else if (v[i] instanceof byte[])
+ elt = hashCode((byte[]) v[i]);
+ else if (v[i] instanceof char[])
+ elt = hashCode((char[]) v[i]);
+ else if (v[i] instanceof short[])
+ elt = hashCode((short[]) v[i]);
+ else if (v[i] instanceof int[])
+ elt = hashCode((int[]) v[i]);
+ else if (v[i] instanceof long[])
+ elt = hashCode((long[]) v[i]);
+ else if (v[i] instanceof float[])
+ elt = hashCode((float[]) v[i]);
+ else if (v[i] instanceof double[])
+ elt = hashCode((double[]) v[i]);
+ else if (v[i] instanceof Object[])
+ elt = hashCode((Object[]) v[i]);
+ else
+ elt = v[i].hashCode();
+ result = 31 * result + elt;
+ }
+ return result;
+ }
+
+ /** @since 1.5 */
+ public static boolean deepEquals(Object[] v1, Object[] v2)
+ {
+ if (v1 == null)
+ return v2 == null;
+ if (v2 == null || v1.length != v2.length)
+ return false;
+
+ for (int i = 0; i < v1.length; ++i)
+ {
+ Object e1 = v1[i];
+ Object e2 = v2[i];
+
+ if (e1 == e2)
+ continue;
+ if (e1 == null || e2 == null)
+ return false;
+
+ boolean check;
+ if (e1 instanceof boolean[] && e2 instanceof boolean[])
+ check = equals((boolean[]) e1, (boolean[]) e2);
+ else if (e1 instanceof byte[] && e2 instanceof byte[])
+ check = equals((byte[]) e1, (byte[]) e2);
+ else if (e1 instanceof char[] && e2 instanceof char[])
+ check = equals((char[]) e1, (char[]) e2);
+ else if (e1 instanceof short[] && e2 instanceof short[])
+ check = equals((short[]) e1, (short[]) e2);
+ else if (e1 instanceof int[] && e2 instanceof int[])
+ check = equals((int[]) e1, (int[]) e2);
+ else if (e1 instanceof long[] && e2 instanceof long[])
+ check = equals((long[]) e1, (long[]) e2);
+ else if (e1 instanceof float[] && e2 instanceof float[])
+ check = equals((float[]) e1, (float[]) e2);
+ else if (e1 instanceof double[] && e2 instanceof double[])
+ check = equals((double[]) e1, (double[]) e2);
+ else if (e1 instanceof Object[] && e2 instanceof Object[])
+ check = equals((Object[]) e1, (Object[]) e2);
+ else
+ check = e1.equals(e2);
+ if (! check)
+ return false;
+ }
+
+ return true;
+ }
+
/**
* Returns a String representation of the argument array. Returns "null"
* if <code>a</code> is null.
@@ -2359,19 +2658,21 @@ public class Arrays
* @return a String representing this array
* @since 1.5
*/
- public static String toString (long[] a)
+ public static String toString(boolean[] v)
{
- if (a == null)
+ if (v == null)
return "null";
- if (a.length == 0)
- return "[]";
- String result = "[";
- for (int i = 0; i < a.length - 1; i++)
- result += String.valueOf(a[i]) + ", ";
- result += String.valueOf(a[a.length - 1]) + "]";
- return result;
- }
-
+ StringBuilder b = new StringBuilder("[");
+ for (int i = 0; i < v.length; ++i)
+ {
+ if (i > 0)
+ b.append(", ");
+ b.append(v[i]);
+ }
+ b.append("]");
+ return b.toString();
+ }
+
/**
* Returns a String representation of the argument array. Returns "null"
* if <code>a</code> is null.
@@ -2379,19 +2680,21 @@ public class Arrays
* @return a String representing this array
* @since 1.5
*/
- public static String toString (int[] a)
+ public static String toString(byte[] v)
{
- if (a == null)
+ if (v == null)
return "null";
- if (a.length == 0)
- return "[]";
- String result = "[";
- for (int i = 0; i < a.length - 1; i++)
- result += String.valueOf(a[i]) + ", ";
- result += String.valueOf(a[a.length - 1]) + "]";
- return result;
- }
-
+ StringBuilder b = new StringBuilder("[");
+ for (int i = 0; i < v.length; ++i)
+ {
+ if (i > 0)
+ b.append(", ");
+ b.append(v[i]);
+ }
+ b.append("]");
+ return b.toString();
+ }
+
/**
* Returns a String representation of the argument array. Returns "null"
* if <code>a</code> is null.
@@ -2399,18 +2702,20 @@ public class Arrays
* @return a String representing this array
* @since 1.5
*/
- public static String toString (short[] a)
+ public static String toString(char[] v)
{
- if (a == null)
+ if (v == null)
return "null";
- if (a.length == 0)
- return "[]";
- String result = "[";
- for (int i = 0; i < a.length - 1; i++)
- result += String.valueOf(a[i]) + ", ";
- result += String.valueOf(a[a.length - 1]) + "]";
- return result;
- }
+ StringBuilder b = new StringBuilder("[");
+ for (int i = 0; i < v.length; ++i)
+ {
+ if (i > 0)
+ b.append(", ");
+ b.append(v[i]);
+ }
+ b.append("]");
+ return b.toString();
+ }
/**
* Returns a String representation of the argument array. Returns "null"
@@ -2419,18 +2724,20 @@ public class Arrays
* @return a String representing this array
* @since 1.5
*/
- public static String toString (char[] a)
+ public static String toString(short[] v)
{
- if (a == null)
+ if (v == null)
return "null";
- if (a.length == 0)
- return "[]";
- String result = "[";
- for (int i = 0; i < a.length - 1; i++)
- result += String.valueOf(a[i]) + ", ";
- result += String.valueOf(a[a.length - 1]) + "]";
- return result;
- }
+ StringBuilder b = new StringBuilder("[");
+ for (int i = 0; i < v.length; ++i)
+ {
+ if (i > 0)
+ b.append(", ");
+ b.append(v[i]);
+ }
+ b.append("]");
+ return b.toString();
+ }
/**
* Returns a String representation of the argument array. Returns "null"
@@ -2439,18 +2746,20 @@ public class Arrays
* @return a String representing this array
* @since 1.5
*/
- public static String toString (byte[] a)
+ public static String toString(int[] v)
{
- if (a == null)
+ if (v == null)
return "null";
- if (a.length == 0)
- return "[]";
- String result = "[";
- for (int i = 0; i < a.length - 1; i++)
- result += String.valueOf(a[i]) + ", ";
- result += String.valueOf(a[a.length - 1]) + "]";
- return result;
- }
+ StringBuilder b = new StringBuilder("[");
+ for (int i = 0; i < v.length; ++i)
+ {
+ if (i > 0)
+ b.append(", ");
+ b.append(v[i]);
+ }
+ b.append("]");
+ return b.toString();
+ }
/**
* Returns a String representation of the argument array. Returns "null"
@@ -2459,18 +2768,20 @@ public class Arrays
* @return a String representing this array
* @since 1.5
*/
- public static String toString (boolean[] a)
+ public static String toString(long[] v)
{
- if (a == null)
+ if (v == null)
return "null";
- if (a.length == 0)
- return "[]";
- String result = "[";
- for (int i = 0; i < a.length - 1; i++)
- result += String.valueOf(a[i]) + ", ";
- result += String.valueOf(a[a.length - 1]) + "]";
- return result;
- }
+ StringBuilder b = new StringBuilder("[");
+ for (int i = 0; i < v.length; ++i)
+ {
+ if (i > 0)
+ b.append(", ");
+ b.append(v[i]);
+ }
+ b.append("]");
+ return b.toString();
+ }
/**
* Returns a String representation of the argument array. Returns "null"
@@ -2479,19 +2790,21 @@ public class Arrays
* @return a String representing this array
* @since 1.5
*/
- public static String toString (float[] a)
+ public static String toString(float[] v)
{
- if (a == null)
+ if (v == null)
return "null";
- if (a.length == 0)
- return "[]";
- String result = "[";
- for (int i = 0; i < a.length - 1; i++)
- result += String.valueOf(a[i]) + ", ";
- result += String.valueOf(a[a.length - 1]) + "]";
- return result;
- }
-
+ StringBuilder b = new StringBuilder("[");
+ for (int i = 0; i < v.length; ++i)
+ {
+ if (i > 0)
+ b.append(", ");
+ b.append(v[i]);
+ }
+ b.append("]");
+ return b.toString();
+ }
+
/**
* Returns a String representation of the argument array. Returns "null"
* if <code>a</code> is null.
@@ -2499,18 +2812,20 @@ public class Arrays
* @return a String representing this array
* @since 1.5
*/
- public static String toString (double[] a)
+ public static String toString(double[] v)
{
- if (a == null)
+ if (v == null)
return "null";
- if (a.length == 0)
- return "[]";
- String result = "[";
- for (int i = 0; i < a.length - 1; i++)
- result += String.valueOf(a[i]) + ", ";
- result += String.valueOf(a[a.length - 1]) + "]";
- return result;
- }
+ StringBuilder b = new StringBuilder("[");
+ for (int i = 0; i < v.length; ++i)
+ {
+ if (i > 0)
+ b.append(", ");
+ b.append(v[i]);
+ }
+ b.append("]");
+ return b.toString();
+ }
/**
* Returns a String representation of the argument array. Returns "null"
@@ -2519,18 +2834,74 @@ public class Arrays
* @return a String representing this array
* @since 1.5
*/
- public static String toString (Object[] a)
+ public static String toString(Object[] v)
{
- if (a == null)
+ if (v == null)
return "null";
- if (a.length == 0)
- return "[]";
- String result = "[";
- for (int i = 0; i < a.length - 1; i++)
- result += String.valueOf(a[i]) + ", ";
- result += String.valueOf(a[a.length - 1]) + "]";
- return result;
- }
+ StringBuilder b = new StringBuilder("[");
+ for (int i = 0; i < v.length; ++i)
+ {
+ if (i > 0)
+ b.append(", ");
+ b.append(v[i]);
+ }
+ b.append("]");
+ return b.toString();
+ }
+
+ private static void deepToString(Object[] v, StringBuilder b, HashSet seen)
+ {
+ b.append("[");
+ for (int i = 0; i < v.length; ++i)
+ {
+ if (i > 0)
+ b.append(", ");
+ Object elt = v[i];
+ if (elt == null)
+ b.append("null");
+ else if (elt instanceof boolean[])
+ b.append(toString((boolean[]) elt));
+ else if (elt instanceof byte[])
+ b.append(toString((byte[]) elt));
+ else if (elt instanceof char[])
+ b.append(toString((char[]) elt));
+ else if (elt instanceof short[])
+ b.append(toString((short[]) elt));
+ else if (elt instanceof int[])
+ b.append(toString((int[]) elt));
+ else if (elt instanceof long[])
+ b.append(toString((long[]) elt));
+ else if (elt instanceof float[])
+ b.append(toString((float[]) elt));
+ else if (elt instanceof double[])
+ b.append(toString((double[]) elt));
+ else if (elt instanceof Object[])
+ {
+ Object[] os = (Object[]) elt;
+ if (seen.contains(os))
+ b.append("[...]");
+ else
+ {
+ seen.add(os);
+ deepToString(os, b, seen);
+ }
+ }
+ else
+ b.append(elt);
+ }
+ b.append("]");
+ }
+
+ /** @since 1.5 */
+ public static String deepToString(Object[] v)
+ {
+ if (v == null)
+ return "null";
+ HashSet seen = new HashSet();
+ StringBuilder b = new StringBuilder();
+ deepToString(v, b, seen);
+ return b.toString();
+ }
/**
* Inner class used by {@link #asList(Object[])} to provide a list interface