diff options
| author | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2006-04-03 20:09:13 +0000 |
|---|---|---|
| committer | Andrew John Hughes <gnu_andrew@member.fsf.org> | 2006-04-03 20:09:13 +0000 |
| commit | 2a8df925bcd276fa213b64d1fca0cf4a52c4040d (patch) | |
| tree | 3bbb67d6bbc77ccaf38bb627c179bf14f3f2554b /java | |
| parent | 3f864b39e567ca569021118e754891eb1956610c (diff) | |
| download | classpath-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.java | 340 | ||||
| -rw-r--r-- | java/lang/reflect/GenericDeclaration.java | 63 | ||||
| -rw-r--r-- | java/lang/reflect/MalformedParameterizedTypeException.java | 58 | ||||
| -rw-r--r-- | java/lang/reflect/TypeVariable.java | 99 | ||||
| -rw-r--r-- | java/util/Arrays.java | 557 |
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<Object></code>, and a dynamic type of + * <code>Class<Rectangle></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<Shape></code>, to retain + * the same instance but with the type + * <code>Class<? extends Shape></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 |
