/*
* @(#)Class.java 1.201 06/08/07
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package java.lang;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Member;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.InvocationTargetException;
import java.lang.ref.SoftReference;
import java.io.InputStream;
import java.io.ObjectStreamField;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
import sun.misc.Unsafe;
import sun.reflect.ConstantPool;
import sun.reflect.Reflection;
import sun.reflect.ReflectionFactory;
import sun.reflect.SignatureIterator;
import sun.reflect.generics.factory.CoreReflectionFactory;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.repository.ClassRepository;
import sun.reflect.generics.repository.MethodRepository;
import sun.reflect.generics.repository.ConstructorRepository;
import sun.reflect.generics.scope.ClassScope;
import sun.security.util.SecurityConstants;
import java.lang.annotation.Annotation;
import sun.reflect.annotation.*;
/**
* Instances of the class <code>Class</code> represent classes and
* interfaces in a running Java application. An enum is a kind of
* class and an annotation is a kind of interface. Every array also
* belongs to a class that is reflected as a <code>Class</code> object
* that is shared by all arrays with the same element type and number
* of dimensions. The primitive Java types (<code>boolean</code>,
* <code>byte</code>, <code>char</code>, <code>short</code>,
* <code>int</code>, <code>long</code>, <code>float</code>, and
* <code>double</code>), and the keyword <code>void</code> are also
* represented as <code>Class</code> objects.
*
* <p> <code>Class</code> has no public constructor. Instead <code>Class</code>
* objects are constructed automatically by the Java Virtual Machine as classes
* are loaded and by calls to the <code>defineClass</code> method in the class
* loader.
*
* <p> The following example uses a <code>Class</code> object to print the
* class name of an object:
*
* <p> <blockquote><pre>
* void printClassName(Object obj) {
* System.out.println("The class of " + obj +
* " is " + obj.getClass().getName());
* }
* </pre></blockquote>
*
* <p> It is also possible to get the <code>Class</code> object for a named
* type (or for void) using a class literal
* (JLS Section <A HREF="http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#251530">15.8.2</A>).
* For example:
*
* <p> <blockquote><pre>
* System.out.println("The name of class Foo is: "+Foo.class.getName());
* </pre></blockquote>
*
* @param <T> the type of the class modeled by this {@code Class}
* object. For example, the type of {@code String.class} is {@code
* Class<String>}. Use {@code Class<?>} if the class being modeled is
* unknown.
*
* @author unascribed
* @version 1.201, 08/07/06
* @see java.lang.ClassLoader#defineClass(byte[], int, int)
* @since JDK1.0
*/
public final
class Class<T> implements java.io.Serializable,
java.lang.reflect.GenericDeclaration,
java.lang.reflect.Type,
java.lang.reflect.AnnotatedElement {
private static final int ANNOTATION= 0x00002000;
private static final int ENUM = 0x00004000;
private static final int SYNTHETIC = 0x00001000;
private static native void registerNatives();
static {
registerNatives();
}
/*
* Constructor. Only the Java Virtual Machine creates Class
* objects.
*/
private Class() {}

/**
* Converts the object to a string. The string representation is the
* string "class" or "interface", followed by a space, and then by the
* fully qualified name of the class in the format returned by
* <code>getName</code>. If this <code>Class</code> object represents a
* primitive type, this method returns the name of the primitive type. If
* this <code>Class</code> object represents void this method returns
* "void".
*
* @return a string representation of this class object.
*/
public String toString() {
return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
+ getName();
}

/**
* Returns the <code>Class</code> object associated with the class or
* interface with the given string name. Invoking this method is
* equivalent to:
*
* <blockquote><pre>
* Class.forName(className, true, currentLoader)
* </pre></blockquote>
*
* where <code>currentLoader</code> denotes the defining class loader of
* the current class.
*
* <p> For example, the following code fragment returns the
* runtime <code>Class</code> descriptor for the class named
* <code>java.lang.Thread</code>:
*
* <blockquote><pre>
* Class t = Class.forName("java.lang.Thread")
* </pre></blockquote>
* <p>
* A call to <tt>forName("X")</tt> causes the class named
* <tt>X</tt> to be initialized.
*
* @param className the fully qualified name of the desired class.
* @return the <code>Class</code> object for the class with the
* specified name.
* @exception LinkageError if the linkage fails
* @exception ExceptionInInitializerError if the initialization provoked
* by this method fails
* @exception ClassNotFoundException if the class cannot be located
*/
public static Class<?> forName(String className)
throws ClassNotFoundException {
return forName0(className, true, ClassLoader.getCallerClassLoader());
}

/**
* Returns the <code>Class</code> object associated with the class or
* interface with the given string name, using the given class loader.
* Given the fully qualified name for a class or interface (in the same
* format returned by <code>getName</code>) this method attempts to
* locate, load, and link the class or interface. The specified class
* loader is used to load the class or interface. If the parameter
* <code>loader</code> is null, the class is loaded through the bootstrap
* class loader. The class is initialized only if the
* <code>initialize</code> parameter is <code>true</code> and if it has
* not been initialized earlier.
*
* <p> If <code>name</code> denotes a primitive type or void, an attempt
* will be made to locate a user-defined class in the unnamed package whose
* name is <code>name</code>. Therefore, this method cannot be used to
* obtain any of the <code>Class</code> objects representing primitive
* types or void.
*
* <p> If <code>name</code> denotes an array class, the component type of
* the array class is loaded but not initialized.
*
* <p> For example, in an instance method the expression:
*
* <blockquote><pre>
* Class.forName("Foo")
* </pre></blockquote>
*
* is equivalent to:
*
* <blockquote><pre>
* Class.forName("Foo", true, this.getClass().getClassLoader())
* </pre></blockquote>
*
* Note that this method throws errors related to loading, linking or
* initializing as specified in Sections 12.2, 12.3 and 12.4 of <em>The
* Java Language Specification</em>.
* Note that this method does not check whether the requested class
* is accessible to its caller.
*
* <p> If the <code>loader</code> is <code>null</code>, and a security
* manager is present, and the caller's class loader is not null, then this
* method calls the security manager's <code>checkPermission</code> method
* with a <code>RuntimePermission("getClassLoader")</code> permission to
* ensure it's ok to access the bootstrap class loader.
*
* @param name fully qualified name of the desired class
* @param initialize whether the class must be initialized
* @param loader class loader from which the class must be loaded
* @return class object representing the desired class
*
* @exception LinkageError if the linkage fails
* @exception ExceptionInInitializerError if the initialization provoked
* by this method fails
* @exception ClassNotFoundException if the class cannot be located by
* the specified class loader
*
* @see java.lang.Class#forName(String)
* @see java.lang.ClassLoader
* @since 1.2
*/
public static Class<?> forName(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException
{
if (loader == null) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = ClassLoader.getCallerClassLoader();
if (ccl != null) {
sm.checkPermission(
SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
}
return forName0(name, initialize, loader);
}
/** Called after security checks have been made. */
private static native Class forName0(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException;
/**
* Creates a new instance of the class represented by this <tt>Class</tt>
* object. The class is instantiated as if by a <code>new</code>
* expression with an empty argument list. The class is initialized if it
* has not already been initialized.
*
* <p>Note that this method propagates any exception thrown by the
* nullary constructor, including a checked exception. Use of
* this method effectively bypasses the compile-time exception
* checking that would otherwise be performed by the compiler.
* The {@link
* java.lang.reflect.Constructor#newInstance(java.lang.Object...)
* Constructor.newInstance} method avoids this problem by wrapping
* any exception thrown by the constructor in a (checked) {@link
* java.lang.reflect.InvocationTargetException}.
*
* @return a newly allocated instance of the class represented by this
* object.
* @exception IllegalAccessException if the class or its nullary
* constructor is not accessible.
* @exception InstantiationException
* if this <code>Class</code> represents an abstract class,
* an interface, an array class, a primitive type, or void;
* or if the class has no nullary constructor;
* or if the instantiation fails for some other reason.
* @exception ExceptionInInitializerError if the initialization
* provoked by this method fails.
* @exception SecurityException
* If a security manager, <i>s</i>, is present and any of the
* following conditions is met:
*
* <ul>
*
* <li> invocation of
* <tt>{@link SecurityManager#checkMemberAccess
* s.checkMemberAccess(this, Member.PUBLIC)}</tt> denies
* creation of new instances of this class
*
* <li> the caller's class loader is not the same as or an
* ancestor of the class loader for the current class and
* invocation of <tt>{@link SecurityManager#checkPackageAccess
* s.checkPackageAccess()}</tt> denies access to the package
* of this class
*
* </ul>
*
*/
public T newInstance()
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
}
return newInstance0();
}
private T newInstance0()
throws InstantiationException, IllegalAccessException
{
// NOTE: the following code may not be strictly correct under
// the current Java memory model.
// Constructor lookup
if (cachedConstructor == null) {
if (this == Class.class) {
throw new IllegalAccessException(
"Can not call newInstance() on the Class for java.lang.Class"
);
}
try {
Class[] empty = {};
final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
// Disable accessibility checks on the constructor
// since we have to do the security check here anyway
// (the stack depth is wrong for the Constructor's
// security check to work)
java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction() {
public Object run() {
c.setAccessible(true);
return null;
}
});
cachedConstructor = c;
} catch (NoSuchMethodException e) {
throw new InstantiationException(getName());
}
}
Constructor<T> tmpConstructor = cachedConstructor;
// Security check (same as in java.lang.reflect.Constructor)
int modifiers = tmpConstructor.getModifiers();
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
Class caller = Reflection.getCallerClass(3);
if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller;
}
}
// Run constructor
try {
return tmpConstructor.newInstance((Object[])null);
} catch (InvocationTargetException e) {
Unsafe.getUnsafe().throwException(e.getTargetException());
// Not reached
return null;
}
}
private volatile transient Constructor<T> cachedConstructor;
private volatile transient Class newInstanceCallerCache;

/**
* Determines if the specified <code>Object</code> is assignment-compatible
* with the object represented by this <code>Class</code>. This method is
* the dynamic equivalent of the Java language <code>instanceof</code>
* operator. The method returns <code>true</code> if the specified
* <code>Object</code> argument is non-null and can be cast to the
* reference type represented by this <code>Class</code> object without
* raising a <code>ClassCastException.</code> It returns <code>false</code>
* otherwise.
*
* <p> Specifically, if this <code>Class</code> object represents a
* declared class, this method returns <code>true</code> if the specified
* <code>Object</code> argument is an instance of the represented class (or
* of any of its subclasses); it returns <code>false</code> otherwise. If
* this <code>Class</code> object represents an array class, this method
* returns <code>true</code> if the specified <code>Object</code> argument
* can be converted to an object of the array class by an identity
* conversion or by a widening reference conversion; it returns
* <code>false</code> otherwise. If this <code>Class</code> object
* represents an interface, this method returns <code>true</code> if the
* class or any superclass of the specified <code>Object</code> argument
* implements this interface; it returns <code>false</code> otherwise. If
* this <code>Class</code> object represents a primitive type, this method
* returns <code>false</code>.
*
* @param obj the object to check
* @return true if <code>obj</code> is an instance of this class
*
* @since JDK1.1
*/
public native boolean isInstance(Object obj);

/**
* Determines if the class or interface represented by this
* <code>Class</code> object is either the same as, or is a superclass or
* superinterface of, the class or interface represented by the specified
* <code>Class</code> parameter. It returns <code>true</code> if so;
* otherwise it returns <code>false</code>. If this <code>Class</code>
* object represents a primitive type, this method returns
* <code>true</code> if the specified <code>Class</code> parameter is
* exactly this <code>Class</code> object; otherwise it returns
* <code>false</code>.
*
* <p> Specifically, this method tests whether the type represented by the
* specified <code>Class</code> parameter can be converted to the type
* represented by this <code>Class</code> object via an identity conversion
* or via a widening reference conversion. See <em>The Java Language
* Specification</em>, sections 5.1.1 and 5.1.4 , for details.
*
* @param cls the <code>Class</code> object to be checked
* @return the <code>boolean</code> value indicating whether objects of the
* type <code>cls</code> can be assigned to objects of this class
* @exception NullPointerException if the specified Class parameter is
* null.
* @since JDK1.1
*/
public native boolean isAssignableFrom(Class<?> cls);

/**
* Determines if the specified <code>Class</code> object represents an
* interface type.
*
* @return <code>true</code> if this object represents an interface;
* <code>false</code> otherwise.
*/
public native boolean isInterface();

/**
* Determines if this <code>Class</code> object represents an array class.
*
* @return <code>true</code> if this object represents an array class;
* <code>false</code> otherwise.
* @since JDK1.1
*/
public native boolean isArray();

/**
* Determines if the specified <code>Class</code> object represents a
* primitive type.
*
* <p> There are nine predefined <code>Class</code> objects to represent
* the eight primitive types and void. These are created by the Java
* Virtual Machine, and have the same names as the primitive types that
* they represent, namely <code>boolean</code>, <code>byte</code>,
* <code>char</code>, <code>short</code>, <code>int</code>,
* <code>long</code>, <code>float</code>, and <code>double</code>.
*
* <p> These objects may only be accessed via the following public static
* final variables, and are the only <code>Class</code> objects for which
* this method returns <code>true</code>.
*
* @return true if and only if this class represents a primitive type
*
* @see java.lang.Boolean#TYPE
* @see java.lang.Character#TYPE
* @see java.lang.Byte#TYPE
* @see java.lang.Short#TYPE
* @see java.lang.Integer#TYPE
* @see java.lang.Long#TYPE
* @see java.lang.Float#TYPE
* @see java.lang.Double#TYPE
* @see java.lang.Void#TYPE
* @since JDK1.1
*/
public native boolean isPrimitive();
/**
* Returns true if this <tt>Class</tt> object represents an annotation
* type. Note that if this method returns true, {@link #isInterface()}
* would also return true, as all annotation types are also interfaces.
*
* @return <tt>true</tt> if this class object represents an annotation
* type; <tt>false</tt> otherwise
* @since 1.5
*/
public boolean isAnnotation() {
return (getModifiers() & ANNOTATION) != 0;
}
/**
* Returns <tt>true</tt> if this class is a synthetic class;
* returns <tt>false</tt> otherwise.
* @return <tt>true</tt> if and only if this class is a synthetic class as
* defined by the Java Language Specification.
* @since 1.5
*/
public boolean isSynthetic() {
return (getModifiers() & SYNTHETIC) != 0;
}
/**
* Returns the name of the entity (class, interface, array class,
* primitive type, or void) represented by this <tt>Class</tt> object,
* as a <tt>String</tt>.
*
* <p> If this class object represents a reference type that is not an
* array type then the binary name of the class is returned, as specified
* by the Java Language Specification, Second Edition.
*
* <p> If this class object represents a primitive type or void, then the
* name returned is a <tt>String</tt> equal to the Java language
* keyword corresponding to the primitive type or void.
*
* <p> If this class object represents a class of arrays, then the internal
* form of the name consists of the name of the element type preceded by
* one or more '<tt>[</tt>' characters representing the depth of the array
* nesting. The encoding of element type names is as follows:
*
* <blockquote><table summary="Element types and encodings">
* <tr><th> Element Type <th> <th> Encoding
* <tr><td> boolean <td> <td align=center> Z
* <tr><td> byte <td> <td align=center> B
* <tr><td> char <td> <td align=center> C
* <tr><td> class or interface
* <td> <td align=center> L<i>classname</i>;
* <tr><td> double <td> <td align=center> D
* <tr><td> float <td> <td align=center> F
* <tr><td> int <td> <td align=center> I
* <tr><td> long <td> <td align=center> J
* <tr><td> short <td> <td align=center> S
* </table></blockquote>
*
* <p> The class or interface name <i>classname</i> is the binary name of
* the class specified above.
*
* <p> Examples:
* <blockquote><pre>
* String.class.getName()
* returns "java.lang.String"
* byte.class.getName()
* returns "byte"
* (new Object[3]).getClass().getName()
* returns "[Ljava.lang.Object;"
* (new int[3][4][5][6][7][8][9]).getClass().getName()
* returns "[[[[[[[I"
* </pre></blockquote>
*
* @return the name of the class or interface
* represented by this object.
*/
public String getName() {
if (name == null)
name = getName0();
return name;
}
// cache the name to reduce the number of calls into the VM
private transient String name;
private native String getName0();
/**
* Returns the class loader for the class. Some implementations may use
* null to represent the bootstrap class loader. This method will return
* null in such implementations if this class was loaded by the bootstrap
* class loader.
*
* <p> If a security manager is present, and the caller's class loader is
* not null and the caller's class loader is not the same as or an ancestor of
* the class loader for the class whose class loader is requested, then
* this method calls the security manager's <code>checkPermission</code>
* method with a <code>RuntimePermission("getClassLoader")</code>
* permission to ensure it's ok to access the class loader for the class.
*
* <p>If this object
* represents a primitive type or void, null is returned.
*
* @return the class loader that loaded the class or interface
* represented by this object.
* @throws SecurityException
* if a security manager exists and its
* <code>checkPermission</code> method denies
* access to the class loader for the class.
* @see java.lang.ClassLoader
* @see SecurityManager#checkPermission
* @see java.lang.RuntimePermission
*/
public ClassLoader getClassLoader() {
ClassLoader cl = getClassLoader0();
if (cl == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = ClassLoader.getCallerClassLoader();
if (ccl != null && ccl != cl && !cl.isAncestor(ccl)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
return cl;
}
// Package-private to allow ClassLoader access
native ClassLoader getClassLoader0();

/**
* Returns an array of <tt>TypeVariable</tt> objects that represent the
* type variables declared by the generic declaration represented by this
* <tt>GenericDeclaration</tt> object, in declaration order. Returns an
* array of length 0 if the underlying generic declaration declares no type
* variables.
*
* @return an array of <tt>TypeVariable</tt> objects that represent
* the type variables declared by this generic declaration
* @throws GenericSignatureFormatError if the generic
* signature of this generic declaration does not conform to
* the format specified in the Java Virtual Machine Specification,
* 3rd edition
* @since 1.5
*/
public TypeVariable<Class<T>>[] getTypeParameters() {
if (getGenericSignature() != null)
return (TypeVariable<Class<T>>[])getGenericInfo().getTypeParameters();
else
return (TypeVariable<Class<T>>[])new TypeVariable[0];
}

/**
* Returns the <code>Class</code> representing the superclass of the entity
* (class, interface, primitive type or void) represented by this
* <code>Class</code>. If this <code>Class</code> represents either the
* <code>Object</code> class, an interface, a primitive type, or void, then
* null is returned. If this object represents an array class then the
* <code>Class</code> object representing the <code>Object</code> class is
* returned.
*
* @return the superclass of the class represented by this object.
*/
public native Class<? super T> getSuperclass();

/**
* Returns the <tt>Type</tt> representing the direct superclass of
* the entity (class, interface, primitive type or void) represented by
* this <tt>Class</tt>.
*
* <p>If the superclass is a parameterized type, the <tt>Type</tt>
* object returned must accurately reflect the actual type
* parameters used in the source code. The parameterized type
* representing the superclass is created if it had not been
* created before. See the declaration of {@link
* java.lang.reflect.ParameterizedType ParameterizedType} for the
* semantics of the creation process for parameterized types. If
* this <tt>Class</tt> represents either the <tt>Object</tt>
* class, an interface, a primitive type, or void, then null is
* returned. If this object represents an array class then the
* <tt>Class</tt> object representing the <tt>Object</tt> class is
* returned.
*
* @throws GenericSignatureFormatError if the generic
* class signature does not conform to the format specified in the
* Java Virtual Machine Specification, 3rd edition
* @throws TypeNotPresentException if the generic superclass
* refers to a non-existent type declaration
* @throws MalformedParameterizedTypeException if the
* generic superclass refers to a parameterized type that cannot be
* instantiated for any reason
* @return the superclass of the class represented by this object
* @since 1.5
*/
public Type getGenericSuperclass() {
if (getGenericSignature() != null) {
// Historical irregularity:
// Generic signature marks interfaces with superclass = Object
// but this API returns null for interfaces
if (isInterface())
return null;
return getGenericInfo().getSuperclass();
} else
return getSuperclass();
}
/**
* Gets the package for this class. The class loader of this class is used
* to find the package. If the class was loaded by the bootstrap class
* loader the set of packages loaded from CLASSPATH is searched to find the
* package of the class. Null is returned if no package object was created
* by the class loader of this class.
*
* <p> Packages have attributes for versions and specifications only if the
* information was defined in the manifests that accompany the classes, and
* if the class loader created the package instance with the attributes
* from the manifest.
*
* @return the package of the class, or null if no package
* information is available from the archive or codebase.
*/
public Package getPackage() {
return Package.getPackage(this);
}

/**
* Determines the interfaces implemented by the class or interface
* represented by this object.
*
* <p> If this object represents a class, the return value is an array
* containing objects representing all interfaces implemented by the
* class. The order of the interface objects in the array corresponds to
* the order of the interface names in the <code>implements</code> clause
* of the declaration of the class represented by this object. For
* example, given the declaration:
* <blockquote><pre>
* class Shimmer implements FloorWax, DessertTopping { ... }
* </pre></blockquote>
* suppose the value of <code>s</code> is an instance of
* <code>Shimmer</code>; the value of the expression:
* <blockquote><pre>
* s.getClass().getInterfaces()[0]
* </pre></blockquote>
* is the <code>Class</code> object that represents interface
* <code>FloorWax</code>; and the value of:
* <blockquote><pre>
* s.getClass().getInterfaces()[1]
* </pre></blockquote>
* is the <code>Class</code> object that represents interface
* <code>DessertTopping</code>.
*
* <p> If this object represents an interface, the array contains objects
* representing all interfaces extended by the interface. The order of the
* interface objects in the array corresponds to the order of the interface
* names in the <code>extends</code> clause of the declaration of the
* interface represented by this object.
*
* <p> If this object represents a class or interface that implements no
* interfaces, the method returns an array of length 0.
*
* <p> If this object represents a primitive type or void, the method
* returns an array of length 0.
*
* @return an array of interfaces implemented by this class.
*/
public native Class<?>[] getInterfaces();
/**
* Returns the <tt>Type</tt>s representing the interfaces
* directly implemented by the class or interface represented by
* this object.
*
* <p>If a superinterface is a parameterized type, the
* <tt>Type</tt> object returned for it must accurately reflect
* the actual type parameters used in the source code. The
* parameterized type representing each superinterface is created
* if it had not been created before. See the declaration of
* {@link java.lang.reflect.ParameterizedType ParameterizedType}
* for the semantics of the creation process for parameterized
* types.
*
* <p> If this object represents a class, the return value is an
* array containing objects representing all interfaces
* implemented by the class. The order of the interface objects in
* the array corresponds to the order of the interface names in
* the <tt>implements</tt> clause of the declaration of the class
* represented by this object. In the case of an array class, the
* interfaces <tt>Cloneable</tt> and <tt>Serializable</tt> are
* returned in that order.
*
* <p>If this object represents an interface, the array contains
* objects representing all interfaces directly extended by the
* interface. The order of the interface objects in the array
* corresponds to the order of the interface names in the
* <tt>extends</tt> clause of the declaration of the interface
* represented by this object.
*
* <p>If this object represents a class or interface that
* implements no interfaces, the method returns an array of length
* 0.
*
* <p>If this object represents a primitive type or void, the
* method returns an array of length 0.
*
* @throws GenericSignatureFormatError
* if the generic class signature does not conform to the format
* specified in the Java Virtual Machine Specification, 3rd edition
* @throws TypeNotPresentException if any of the generic
* superinterfaces refers to a non-existent type declaration
* @throws MalformedParameterizedTypeException if any of the
* generic superinterfaces refer to a parameterized type that cannot
* be instantiated for any reason
* @return an array of interfaces implemented by this class
* @since 1.5
*/
public Type[] getGenericInterfaces() {
if (getGenericSignature() != null)
return getGenericInfo().getSuperInterfaces();
else
return getInterfaces();
}

/**
* Returns the <code>Class</code> representing the component type of an
* array. If this class does not represent an array class this method