/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * Copyright (C) 2006-2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package java.lang; import com.android.dex.Dex; import dalvik.system.VMStack; import java.io.InputStream; import java.io.Serializable; import java.lang.annotation.Annotation; import java.lang.annotation.Inherited; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.GenericDeclaration; 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.ProtectionDomain; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import org.apache.harmony.kernel.vm.StringUtils; import libcore.reflect.AnnotationAccess; import libcore.reflect.GenericSignatureParser; import libcore.reflect.InternalNames; import libcore.reflect.Types; import libcore.util.BasicLruCache; import libcore.util.CollectionUtils; import libcore.util.EmptyArray; /** * The in-memory representation of a Java class. This representation serves as * the starting point for querying class-related information, a process usually * called "reflection". There are basically three types of {@code Class} * instances: those representing real classes and interfaces, those representing * primitive types, and those representing array classes. * *
* These represent an ordinary class or interface as found in the class * hierarchy. The name associated with these {@code Class} instances is simply * the fully qualified class name of the class or interface that it represents. * In addition to this human-readable name, each class is also associated by a * so-called signature, which is the letter "L", followed by the * class name and a semicolon (";"). The signature is what the runtime system * uses internally for identifying the class (for example in a DEX file). *
** These represent the standard Java primitive types and hence share their * names (for example "int" for the {@code int} primitive type). Although it is * not possible to create new instances based on these {@code Class} instances, * they are still useful for providing reflection information, and as the * component type of array classes. There is one {@code Class} instance for each * primitive type, and their signatures are: *
**
* These represent the classes of Java arrays. There is one such {@code Class} * instance per combination of array leaf component type and arity (number of * dimensions). In this case, the name associated with the {@code Class} * consists of one or more left square brackets (one per dimension in the array) * followed by the signature of the class representing the leaf component type, * which can be either an object type or a primitive type. The signature of a * {@code Class} representing an array type is the same as its name. Examples * of array class signatures are: *
*If the class has not yet been loaded, it is loaded and initialized * first. This is done through either the class loader of the calling class * or one of its parent class loaders. It is possible that a static initializer is run as * a result of this call. * * @throws ClassNotFoundException * if the requested class can not be found. * @throws LinkageError * if an error occurs during linkage * @throws ExceptionInInitializerError * if an exception occurs during static initialization of a * class. */ public static Class> forName(String className) throws ClassNotFoundException { return forName(className, true, VMStack.getCallingClassLoader()); } /** * Returns a {@code Class} object which represents the class with the * given name. The name should be the name of a non-primitive class, as described in * the {@link Class class definition}. * Primitive types can not be found using this method; use {@code int.class} or {@code Integer.TYPE} instead. * *
If the class has not yet been loaded, it is loaded first, using the given class loader.
* If the class has not yet been initialized and {@code shouldInitialize} is true,
* the class will be initialized.
*
* @throws ClassNotFoundException
* if the requested class can not be found.
* @throws LinkageError
* if an error occurs during linkage
* @throws ExceptionInInitializerError
* if an exception occurs during static initialization of a
* class.
*/
public static Class> forName(String className, boolean shouldInitialize,
ClassLoader classLoader) throws ClassNotFoundException {
if (classLoader == null) {
classLoader = ClassLoader.getSystemClassLoader();
}
// Catch an Exception thrown by the underlying native code. It wraps
// up everything inside a ClassNotFoundException, even if e.g. an
// Error occurred during initialization. This as a workaround for
// an ExceptionInInitializerError that's also wrapped. It is actually
// expected to be thrown. Maybe the same goes for other errors.
// Not wrapping up all the errors will break android though.
Class> result;
try {
result = classForName(className, shouldInitialize,
classLoader);
} catch (ClassNotFoundException e) {
Throwable cause = e.getCause();
if (cause instanceof ExceptionInInitializerError) {
throw (ExceptionInInitializerError) cause;
}
throw e;
}
return result;
}
private static native Class> classForName(String className, boolean shouldInitialize,
ClassLoader classLoader) throws ClassNotFoundException;
/**
* Returns an array containing {@code Class} objects for all public classes
* and interfaces that are members of this class. This includes public
* members inherited from super classes and interfaces. If there are no such
* class members or if this object represents a primitive type then an array
* of length 0 is returned.
*/
public Class>[] getClasses() {
Class>[] result = getDeclaredClasses(this, true);
// Traverse all superclasses.
for (Class> c = this.getSuperclass(); c != null; c = c.getSuperclass()) {
Class>[] temp = getDeclaredClasses(c, true);
if (temp.length != 0) {
result = arraycopy(new Class[result.length + temp.length], result, temp);
}
}
return result;
}
@Override public A getAnnotation(Class annotationType) {
if (annotationType == null) {
throw new NullPointerException("annotationType == null");
}
A annotation = getDeclaredAnnotation(annotationType);
if (annotation != null) {
return annotation;
}
if (annotationType.isAnnotationPresent(Inherited.class)) {
for (Class> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
annotation = sup.getDeclaredAnnotation(annotationType);
if (annotation != null) {
return annotation;
}
}
}
return null;
}
/**
* Returns an array containing all the annotations of this class. If there are no annotations
* then an empty array is returned.
*
* @see #getDeclaredAnnotations()
*/
public Annotation[] getAnnotations() {
/*
* We need to get the annotations declared on this class, plus the
* annotations from superclasses that have the "@Inherited" annotation
* set. We create a temporary map to use while we accumulate the
* annotations and convert it to an array at the end.
*
* It's possible to have duplicates when annotations are inherited.
* We use a Map to filter those out.
*
* HashMap might be overkill here.
*/
HashMap See {@link #getMethod} for details of the search order.
* Use {@link #getDeclaredConstructor} if you don't want to search superclasses.
*
* @throws NoSuchMethodException
* if the constructor can not be found.
*/
@SuppressWarnings("unchecked")
public Constructor Use {@link #getConstructor} if you want to search superclasses.
*
* @throws NoSuchMethodException
* if the requested constructor can not be found.
*/
@SuppressWarnings("unchecked")
public Constructor See {@link #getMethod} if you want to search superclasses.
*
* @throws NoSuchMethodException
* if the requested method can not be found.
* @throws NullPointerException
* if {@code name} is {@code null}.
*/
public Method getDeclaredMethod(String name, Class>... parameterTypes)
throws NoSuchMethodException {
Member member = getConstructorOrMethod(name, false, false, parameterTypes);
if (member instanceof Constructor) {
throw new NoSuchMethodException(name);
}
return (Method) member;
}
/**
* Returns an array containing {@code Method} objects for all methods
* declared in the class represented by this {@code Class}. If there are no
* methods or if this {@code Class} represents an array class, a primitive
* type or void then an empty array is returned.
*
* @see #getMethods()
*/
public Method[] getDeclaredMethods() {
return getDeclaredMethods(this, false);
}
/**
* Returns the list of methods. If no methods exist, an empty array is returned.
*/
static native Method[] getDeclaredMethods(Class> c, boolean publicOnly);
/**
* Returns the constructor or method if it is defined by {@code c}; null
* otherwise. This may return a non-public member. Use " If there are no public fields or if this class represents an array class,
* a primitive type or {@code void} then an empty array is returned.
*
* @see #getDeclaredFields()
*/
public Field[] getFields() {
List This method first searches the class C represented by this {@code Class},
* then the superclasses of C,
* and finally the interfaces implemented by C and its superclasses.
*
* Use {@link #getDeclaredMethod} if you don't want to search superclasses.
*
* @throws NoSuchMethodException
* if the method can not be found.
*/
public Method getMethod(String name, Class>... parameterTypes) throws NoSuchMethodException {
Member member = getConstructorOrMethod(name, true, true, parameterTypes);
if (member instanceof Constructor) {
throw new NoSuchMethodException(name);
}
return (Method) member;
}
/**
* Returns an array containing {@code Method} objects for all public methods
* for the class C represented by this {@code Class}. Methods may be
* declared in C, the interfaces it implements or in the superclasses of C.
* The elements in the returned array are in no particular order.
*
* If there are no public methods or if this {@code Class} represents a
* primitive type or {@code void} then an empty array is returned.
*
* @see #getDeclaredMethods()
*/
public Method[] getMethods() {
List