Class.java revision 5346a96c353933579db184a8433fc0cc1e076950
12cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom/*
22cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * Licensed to the Apache Software Foundation (ASF) under one or more
32cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * contributor license agreements.  See the NOTICE file distributed with
42cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * this work for additional information regarding copyright ownership.
52cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * The ASF licenses this file to You under the Apache License, Version 2.0
62cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * (the "License"); you may not use this file except in compliance with
72cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * the License.  You may obtain a copy of the License at
82cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom *
92cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom *     http://www.apache.org/licenses/LICENSE-2.0
102cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom *
112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * Unless required by applicable law or agreed to in writing, software
122cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
132cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * See the License for the specific language governing permissions and
152cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * limitations under the License.
162cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom */
172cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom/*
182cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * Copyright (C) 2006-2007 The Android Open Source Project
192cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom *
202cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
212cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * you may not use this file except in compliance with the License.
222cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * You may obtain a copy of the License at
232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom *
242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
252cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom *
262cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * Unless required by applicable law or agreed to in writing, software
272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * See the License for the specific language governing permissions and
302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * limitations under the License.
312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom */
322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
332cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrompackage java.lang;
342cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
352cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport com.android.dex.Dex;
362cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport dalvik.system.VMStack;
372cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.io.InputStream;
382cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.io.Serializable;
392cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.lang.annotation.Annotation;
402cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.lang.reflect.AccessibleObject;
412cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.lang.reflect.AnnotatedElement;
4271dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstromimport java.lang.reflect.ArtField;
4371dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstromimport java.lang.reflect.ArtMethod;
442cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.lang.reflect.Constructor;
452cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.lang.reflect.Field;
462cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.lang.reflect.GenericDeclaration;
472cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.lang.reflect.InvocationTargetException;
482cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.lang.reflect.Member;
492cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.lang.reflect.Method;
502cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.lang.reflect.Modifier;
512cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.lang.reflect.Type;
522cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.lang.reflect.TypeVariable;
532cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.net.URL;
545346a96c353933579db184a8433fc0cc1e076950Narayan Kamathimport java.nio.charset.StandardCharsets;
552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.security.ProtectionDomain;
562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.util.ArrayList;
572cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.util.Arrays;
582cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport java.util.List;
592cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport libcore.reflect.AnnotationAccess;
602cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport libcore.reflect.GenericSignatureParser;
612cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport libcore.reflect.InternalNames;
622cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport libcore.reflect.Types;
63a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogersimport libcore.util.BasicLruCache;
642cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport libcore.util.CollectionUtils;
652cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstromimport libcore.util.EmptyArray;
66793b9ef91876cb7bea31ddf74f110ac45302f1ddJeff Haoimport libcore.util.SneakyThrow;
672cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom/**
692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * The in-memory representation of a Java class. This representation serves as
702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * the starting point for querying class-related information, a process usually
712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * called "reflection". There are basically three types of {@code Class}
722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * instances: those representing real classes and interfaces, those representing
732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * primitive types, and those representing array classes.
742cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom *
752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <h4>Class instances representing object types (classes or interfaces)</h4>
762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <p>
772cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * These represent an ordinary class or interface as found in the class
782cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * hierarchy. The name associated with these {@code Class} instances is simply
792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * the fully qualified class name of the class or interface that it represents.
802cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * In addition to this human-readable name, each class is also associated by a
812cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * so-called <em>descriptor</em>, which is the letter "L", followed by the
822cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * class name and a semicolon (";"). The descriptor is what the runtime system
832cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * uses internally for identifying the class (for example in a DEX file).
842cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * </p>
852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <h4>Classes representing primitive types</h4>
862cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <p>
872cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * These represent the standard Java primitive types and hence share their
882cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * names (for example "int" for the {@code int} primitive type). Although it is
892cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * not possible to create new instances based on these {@code Class} instances,
902cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * they are still useful for providing reflection information, and as the
912cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * component type of array classes. There is one {@code Class} instance for each
922cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * primitive type, and their descriptors are:
932cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * </p>
942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <ul>
952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <li>{@code B} representing the {@code byte} primitive type</li>
962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <li>{@code S} representing the {@code short} primitive type</li>
972cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <li>{@code I} representing the {@code int} primitive type</li>
982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <li>{@code J} representing the {@code long} primitive type</li>
992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <li>{@code F} representing the {@code float} primitive type</li>
1002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <li>{@code D} representing the {@code double} primitive type</li>
1012cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <li>{@code C} representing the {@code char} primitive type</li>
1022cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <li>{@code Z} representing the {@code boolean} primitive type</li>
1032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <li>{@code V} representing void function return values</li>
1042cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * </ul>
1052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <p>
1062cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <h4>Classes representing array classes</h4>
1072cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <p>
1082cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * These represent the classes of Java arrays. There is one such {@code Class}
1092cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * instance per combination of array leaf component type and arity (number of
1102cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * dimensions). In this case, the name associated with the {@code Class}
1112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * consists of one or more left square brackets (one per dimension in the array)
1122cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * followed by the descriptor of the class representing the leaf component type,
1132cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * which can be either an object type or a primitive type. The descriptor of a
1142cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * {@code Class} representing an array type is the same as its name. Examples
1152cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * of array class descriptors are:
1162cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * </p>
1172cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <ul>
1182cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <li>{@code [I} representing the {@code int[]} type</li>
1192cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <li>{@code [Ljava/lang/String;} representing the {@code String[]} type</li>
1202cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * <li>{@code [[[C} representing the {@code char[][][]} type (three dimensions!)</li>
1212cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom * </ul>
1222cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom */
1232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrompublic final class Class<T> implements Serializable, AnnotatedElement, GenericDeclaration, Type {
1242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
1252cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private static final long serialVersionUID = 3206093459760846163L;
1262cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
1272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /** defining class loader, or NULL for the "bootstrap" system loader. */
1282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient ClassLoader classLoader;
1292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
1302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
1312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * For array classes, the component class object for instanceof/checkcast (for String[][][],
1322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * this will be String[][]). NULL for non-array classes.
1332cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
1342cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient Class<?> componentType;
1352cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
1362cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * DexCache of resolved constant pool entries. Will be null for certain VM-generated classes
1372cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * e.g. arrays and primitive classes.
1382cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
1392cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient DexCache dexCache;
1402cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
1412cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /** static, private, and &lt;init&gt; methods. */
14271dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom    private transient ArtMethod[] directMethods;
1432cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
1442cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
1452cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Instance fields. These describe the layout of the contents of an Object. Note that only the
1462cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * fields directly declared by this class are listed in iFields; fields declared by a
1472cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * superclass are listed in the superclass's Class.iFields.
1482cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
1492cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * All instance fields that refer to objects are guaranteed to be at the beginning of the field
1502cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * list.  {@link Class#numReferenceInstanceFields} specifies the number of reference fields.
1512cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
15271dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom    private transient ArtField[] iFields;
1532cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
1542cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
1552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * The interface table (iftable_) contains pairs of a interface class and an array of the
1562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * interface methods. There is one pair per interface supported by this class.  That
1572cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * means one pair for each interface we support directly, indirectly via superclass, or
1582cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * indirectly via a superinterface.  This will be null if neither we nor our superclass
1592cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * implement any interfaces.
1602cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
1612cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()".
1622cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Invoke faceObj.blah(), where "blah" is part of the Face interface.  We can't easily use a
1632cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * single vtable.
1642cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
1652cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * For every interface a concrete class implements, we create an array of the concrete vtable_
1662cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * methods for the methods in the interface.
1672cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
1682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient Object[] ifTable;
1692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
1702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /** Lazily computed name of this class; always prefer calling getName(). */
1712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient String name;
1722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
1732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /** Static fields */
17471dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom    private transient ArtField[] sFields;
1752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
1762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /** The superclass, or NULL if this is java.lang.Object, an interface or primitive type. */
1772cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient Class<? super T> superClass;
1782cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
1792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /** If class verify fails, we must return same error on subsequent tries. */
1802cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient Class<?> verifyErrorClass;
1812cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
1822cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /** Virtual methods defined in this class; invoked through vtable. */
18371dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom    private transient ArtMethod[] virtualMethods;
1842cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
1852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
1862cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass
1872cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * is copied in, and virtual methods from our class either replace those from the super or are
1882cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * appended. For abstract classes, methods may be created in the vtable that aren't in
1892cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * virtual_ methods_ for miranda methods.
1902cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
19171dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom    private transient ArtMethod[] vtable;
1922cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
1932cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /** access flags; low 16 bits are defined by VM spec */
1942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient int accessFlags;
1952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
1962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
1972cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Total size of the Class instance; used when allocating storage on GC heap.
1982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * See also {@link Class#objectSize}.
1992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
2002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient int classSize;
2012cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
2022cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
2032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * tid used to check for recursive static initializer invocation.
2042cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
2052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient int clinitThreadId;
2062cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
2072cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
208a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     * Class def index from dex file. An index of 65535 indicates that there is no class definition,
209a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     * for example for an array type.
210a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     * TODO: really 16bits as type indices are 16bit.
2112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
212a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers    private transient int dexClassDefIndex;
213a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers
214a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers    /**
215a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     * Class type index from dex file, lazily computed. An index of 65535 indicates that the type
216a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     * index isn't known. Volatile to avoid double-checked locking bugs.
217a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     * TODO: really 16bits as type indices are 16bit.
218a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     */
219a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers    private transient volatile int dexTypeIndex;
2202cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
2212cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /** Number of instance fields that are object references. */
2222cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient int numReferenceInstanceFields;
2232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
2242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /** Number of static fields that are object references. */
2252cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient int numReferenceStaticFields;
2262cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
2272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
2282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Total object size; used when allocating storage on GC heap. For interfaces and abstract
2292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * classes this will be zero. See also {@link Class#classSize}.
2302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
2312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient int objectSize;
2322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
233c519ec27ba900d5422c5a0d40388fb6620981564Hiroshi Yamauchi    /**
234c519ec27ba900d5422c5a0d40388fb6620981564Hiroshi Yamauchi     * The lower 16 bits is the primitive type value, or 0 if not a primitive type; set for
235c519ec27ba900d5422c5a0d40388fb6620981564Hiroshi Yamauchi     * generated primitive classes.
236c519ec27ba900d5422c5a0d40388fb6620981564Hiroshi Yamauchi     */
2372cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient int primitiveType;
2382cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
2392cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /** Bitmap of offsets of iFields. */
2402cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient int referenceInstanceOffsets;
2412cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
2422cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /** State of class initialization */
2432cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private transient int status;
2442cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
2452cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private Class() {
2462cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // Prevent this class to be instantiated, instance should be created by JVM only
2472cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
2482cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
2492cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
25071dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * Returns a {@code Class} object which represents the class with
25171dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * the given name. The name should be the name of a non-primitive
25271dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * class, as described in the {@link Class class definition}.
25371dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * Primitive types can not be found using this method; use {@code
25471dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * int.class} or {@code Integer.TYPE} instead.
2552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
2562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * <p>If the class has not yet been loaded, it is loaded and initialized
2572cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * first. This is done through either the class loader of the calling class
2582cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * or one of its parent class loaders. It is possible that a static initializer is run as
2592cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * a result of this call.
2602cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
2612cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws ClassNotFoundException
2622cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if the requested class cannot be found.
2632cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws LinkageError
2642cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if an error occurs during linkage
2652cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws ExceptionInInitializerError
2662cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if an exception occurs during static initialization of a
2672cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             class.
2682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
2692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public static Class<?> forName(String className) throws ClassNotFoundException {
2702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return forName(className, true, VMStack.getCallingClassLoader());
2712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
2722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
2732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
27471dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * Returns a {@code Class} object which represents the class with
27571dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * the given name. The name should be the name of a non-primitive
27671dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * class, as described in the {@link Class class definition}.
27771dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * Primitive types can not be found using this method; use {@code
27871dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * int.class} or {@code Integer.TYPE} instead.
2792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
2802cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * <p>If the class has not yet been loaded, it is loaded first, using the given class loader.
2812cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * If the class has not yet been initialized and {@code shouldInitialize} is true,
2822cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * the class will be initialized.
2832cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
2842cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws ClassNotFoundException
2852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if the requested class cannot be found.
2862cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws LinkageError
2872cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if an error occurs during linkage
2882cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws ExceptionInInitializerError
2892cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if an exception occurs during static initialization of a
2902cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             class.
2912cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
2922cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public static Class<?> forName(String className, boolean shouldInitialize,
2932cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            ClassLoader classLoader) throws ClassNotFoundException {
2942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
2952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (classLoader == null) {
2962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            classLoader = ClassLoader.getSystemClassLoader();
2972cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
2982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // Catch an Exception thrown by the underlying native code. It wraps
2992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // up everything inside a ClassNotFoundException, even if e.g. an
3002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // Error occurred during initialization. This as a workaround for
3012cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // an ExceptionInInitializerError that's also wrapped. It is actually
3022cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // expected to be thrown. Maybe the same goes for other errors.
3032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // Not wrapping up all the errors will break android though.
3042cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        Class<?> result;
3052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        try {
3062cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            result = classForName(className, shouldInitialize, classLoader);
3072cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } catch (ClassNotFoundException e) {
3082cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            Throwable cause = e.getCause();
3092cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            if (cause instanceof LinkageError) {
3102cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                throw (LinkageError) cause;
3112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
3122cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            throw e;
3132cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
3142cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return result;
3152cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
3162cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
3172cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    static native Class<?> classForName(String className, boolean shouldInitialize,
3182cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            ClassLoader classLoader) throws ClassNotFoundException;
3192cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
3202cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
32171dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * Returns an array containing {@code Class} objects for all
32271dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * public classes, interfaces, enums and annotations that are
32371dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * members of this class and its superclasses. This does not
32471dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * include classes of implemented interfaces.  If there are no
32571dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * such class members or if this object represents a primitive
32671dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom     * type then an array of length 0 is returned.
3272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
3282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Class<?>[] getClasses() {
3292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        List<Class<?>> result = new ArrayList<Class<?>>();
3302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        for (Class<?> c = this; c != null; c = c.superClass) {
3312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            for (Class<?> member : c.getDeclaredClasses()) {
3322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                if (Modifier.isPublic(member.getModifiers())) {
3332cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    result.add(member);
3342cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                }
3352cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
3362cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
3372cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return result.toArray(new Class[result.size()]);
3382cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
3392cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
3402cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
3412cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return AnnotationAccess.getAnnotation(this, annotationType);
3422cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
3432cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
3442cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
3452cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns an array containing all the annotations of this class. If there are no annotations
3462cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * then an empty array is returned.
3472cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
3482cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see #getDeclaredAnnotations()
3492cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
3502cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    @Override public Annotation[] getAnnotations() {
3512cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return AnnotationAccess.getAnnotations(this);
3522cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
3532cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
3542cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
3552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the canonical name of this class. If this class does not have a
3562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * canonical name as defined in the Java Language Specification, then the
3572cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * method returns {@code null}.
3582cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
3592cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public String getCanonicalName() {
3602cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (isLocalClass() || isAnonymousClass())
3612cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return null;
3622cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
3632cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (isArray()) {
3642cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            /*
3652cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom             * The canonical name of an array type depends on the (existence of)
3662cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom             * the component type's canonical name.
3672cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom             */
3682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            String name = getComponentType().getCanonicalName();
3692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            if (name != null) {
3702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                return name + "[]";
3712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
3722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else if (isMemberClass()) {
3732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            /*
3742cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom             * The canonical name of an inner class depends on the (existence
3752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom             * of) the declaring class' canonical name.
3762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom             */
3772cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            String name = getDeclaringClass().getCanonicalName();
3782cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            if (name != null) {
3792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                return name + "." + getSimpleName();
3802cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
3812cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else {
3822cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            /*
3832cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom             * The canonical name of a top-level class or primitive type is
3842cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom             * equal to the fully qualified name.
3852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom             */
3862cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return getName();
3872cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
3882cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
3892cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        /*
3902cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom         * Other classes don't have a canonical name.
3912cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom         */
3922cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return null;
3932cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
3942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
3952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
3962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the class loader which was used to load the class represented by
3972cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * this {@code Class}. Implementations are free to return {@code null} for
3982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * classes that were loaded by the bootstrap class loader. The Android
3992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * reference implementation, though, always returns a reference to an actual
4002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * class loader.
4012cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
4022cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public ClassLoader getClassLoader() {
4032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (this.isPrimitive()) {
4042cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return null;
4052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
4062cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
4072cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        ClassLoader loader = getClassLoaderImpl();
4082cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (loader == null) {
4092cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            loader = BootClassLoader.getInstance();
4102cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
4112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return loader;
4122cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
4132cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
4142cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
4152cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * This must be provided by the VM vendor, as it is used by other provided
4162cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * class implementations in this package. Outside of this class, it is used
4172cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * by SecurityManager.classLoaderDepth(),
4182cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * currentClassLoader() and currentLoadedClass(). Return the ClassLoader for
4192cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * this Class without doing any security checks. The bootstrap ClassLoader
4202cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * is returned, unlike getClassLoader() which returns null in place of the
4212cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * bootstrap ClassLoader.
4222cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
4232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    ClassLoader getClassLoaderImpl() {
4242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        ClassLoader loader = classLoader;
4252cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return loader == null ? BootClassLoader.getInstance() : loader;
4262cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
4272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
4282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
4292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns a {@code Class} object which represents the component type if
4302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * this class represents an array type. Returns {@code null} if this class
4312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * does not represent an array type. The component type of an array type is
4322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * the type of the elements of the array.
4332cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
4342cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Class<?> getComponentType() {
4352cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom      return componentType;
4362cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
4372cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
4382cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
4392cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the dex file from which this class was loaded.
4402cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
4412cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @hide
4422cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
443a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers    public Dex getDex() {
444a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        if (dexCache == null) {
445a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers            return null;
446a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        }
447a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        return dexCache.getDex();
448a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers    }
4492cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
4502cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
451a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     * Returns a string from the dex cache, computing the string from the dex file if necessary.
4522cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
4532cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @hide
4542cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
4552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public String getDexCacheString(Dex dex, int dexStringIndex) {
4562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        String[] dexCacheStrings = dexCache.strings;
4572cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        String s = dexCacheStrings[dexStringIndex];
4582cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (s == null) {
459a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers            s = dex.strings().get(dexStringIndex).intern();
4602cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            dexCacheStrings[dexStringIndex] = s;
4612cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
4622cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return s;
4632cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
4642cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
4652cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
466a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     * Returns a resolved type from the dex cache, computing the type from the dex file if
467a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     * necessary.
4682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
4692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @hide
4702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
4712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Class<?> getDexCacheType(Dex dex, int dexTypeIndex) {
4722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        Class<?>[] dexCacheResolvedTypes = dexCache.resolvedTypes;
4732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        Class<?> resolvedType = dexCacheResolvedTypes[dexTypeIndex];
4742cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (resolvedType == null) {
4752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            int descriptorIndex = dex.typeIds().get(dexTypeIndex);
4762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            String descriptor = getDexCacheString(dex, descriptorIndex);
4772cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            resolvedType = InternalNames.getClass(getClassLoader(), descriptor);
4782cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            dexCacheResolvedTypes[dexTypeIndex] = resolvedType;
4792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
4802cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return resolvedType;
4812cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
4822cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
4832cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
4842cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns a {@code Constructor} object which represents the public
4852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * constructor matching the given parameter types.
4862cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * {@code (Class[]) null} is equivalent to the empty array.
4872cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
4882cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws NoSuchMethodException
4892cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if the constructor cannot be found.
4902cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see #getDeclaredConstructor(Class[])
4912cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
4922cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException {
4932cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return getConstructor(parameterTypes, true);
4942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
4952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
4962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
4972cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns a {@code Constructor} object which represents the constructor
4982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * matching the specified parameter types that is declared by the class
4992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * represented by this {@code Class}.
5002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * {@code (Class[]) null} is equivalent to the empty array.
5012cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
5022cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws NoSuchMethodException
5032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if the requested constructor cannot be found.
5042cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see #getConstructor(Class[])
5052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
5062cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
5072cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            throws NoSuchMethodException {
5082cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return getConstructor(parameterTypes, false);
5092cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
5102cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
5112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
5122cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns a constructor with the given parameters.
5132cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
5142cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @param publicOnly true to only return public constructores.
5152cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @param parameterTypes argument types to match the constructor's.
5162cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
5172cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private Constructor<T> getConstructor(Class<?>[] parameterTypes, boolean publicOnly)
5182cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            throws NoSuchMethodException {
5192cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (parameterTypes == null) {
5202cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            parameterTypes = EmptyArray.CLASS;
5212cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
5222cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        for (Class<?> c : parameterTypes) {
5232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            if (c == null) {
5242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                throw new NoSuchMethodException("parameter type is null");
5252cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
5262cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
5272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        Constructor<T> result = getDeclaredConstructorInternal(parameterTypes);
5282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (result == null || publicOnly && !Modifier.isPublic(result.getAccessFlags())) {
5292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            throw new NoSuchMethodException("<init> " + Arrays.toString(parameterTypes));
5302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
5312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return result;
5322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
5332cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
5342cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
5352cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the constructor with the given parameters if it is defined by this class; null
5362cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * otherwise. This may return a non-public member.
5372cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
5382cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @param args the types of the parameters to the constructor.
5392cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
5402cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private Constructor<T> getDeclaredConstructorInternal(Class<?>[] args) {
5412cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (directMethods != null) {
54271dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom            for (ArtMethod m : directMethods) {
54371dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                int modifiers = m.getAccessFlags();
54471dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                if (Modifier.isStatic(modifiers)) {
54571dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    // skip <clinit> which is a static constructor
54671dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    continue;
54771dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                }
54871dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                if (!Modifier.isConstructor(modifiers)) {
54971dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    continue;
55071dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                }
55171dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                if (!ArtMethod.equalConstructorParameters(m, args)) {
55271dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    continue;
5532cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                }
55471dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                return new Constructor<T>(m);
5552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
5562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
5572cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return null;
5582cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
5592cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
5602cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
5612cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns an array containing {@code Constructor} objects for all public
5622cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * constructors for this {@code Class}. If there
5632cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * are no public constructors or if this {@code Class} represents an array
5642cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * class, a primitive type or void then an empty array is returned.
5652cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
5662cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see #getDeclaredConstructors()
5672cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
5682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Constructor<?>[] getConstructors() {
5692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        ArrayList<Constructor<T>> constructors = new ArrayList();
5702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        getDeclaredConstructors(true, constructors);
5712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return constructors.toArray(new Constructor[constructors.size()]);
5722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
5732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
5742cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
5752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns an array containing {@code Constructor} objects for all
5762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * constructors declared in the class represented by this {@code Class}. If
5772cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * there are no constructors or if this {@code Class} represents an array
5782cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * class, a primitive type or void then an empty array is returned.
5792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
5802cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see #getConstructors()
5812cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
5822cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Constructor<?>[] getDeclaredConstructors() {
5832cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        ArrayList<Constructor<T>> constructors = new ArrayList();
5842cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        getDeclaredConstructors(false, constructors);
5852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return constructors.toArray(new Constructor[constructors.size()]);
5862cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
5872cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
5882cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private void getDeclaredConstructors(boolean publicOnly, List<Constructor<T>> constructors) {
5892cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (directMethods != null) {
59071dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom            for (ArtMethod m : directMethods) {
5912cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                int modifiers = m.getAccessFlags();
5922cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                if (!publicOnly || Modifier.isPublic(modifiers)) {
59371dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    if (Modifier.isStatic(modifiers)) {
59471dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                        // skip <clinit> which is a static constructor
59571dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                        continue;
59671dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    }
59771dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    if (Modifier.isConstructor(modifiers)) {
59871dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                        constructors.add(new Constructor<T>(m));
5992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    }
6002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                }
6012cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
6022cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
6032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
6042cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
6052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
6062cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns a {@code Method} object which represents the method matching the
6072cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * specified name and parameter types that is declared by the class
6082cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * represented by this {@code Class}.
6092cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
6102cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @param name
6112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *            the requested method's name.
6122cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @param parameterTypes
6132cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *            the parameter types of the requested method.
6142cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *            {@code (Class[]) null} is equivalent to the empty array.
6152cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @return the method described by {@code name} and {@code parameterTypes}.
6162cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws NoSuchMethodException
6172cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if the requested constructor cannot be found.
6182cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws NullPointerException
6192cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if {@code name} is {@code null}.
6202cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see #getMethod(String, Class[])
6212cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
6222cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
6232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            throws NoSuchMethodException {
6242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return getMethod(name, parameterTypes, false);
6252cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
6262cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
6272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
6282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns a {@code Method} object which represents the public method with
6292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * the specified name and parameter types.
6302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * {@code (Class[]) null} is equivalent to the empty array.
6312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * This method first searches the
6322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * class C represented by this {@code Class}, then the superclasses of C and
6332cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * finally the interfaces implemented by C and finally the superclasses of C
6342cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * for a method with matching name.
6352cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
6362cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws NoSuchMethodException
6372cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if the method cannot be found.
6382cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see #getDeclaredMethod(String, Class[])
6392cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
6402cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException {
6412cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return getMethod(name, parameterTypes, true);
6422cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
6432cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
64478728ebce868f5949739e6e204e3e0fbf0356f8dElliott Hughes    private Method getMethod(String name, Class<?>[] parameterTypes, boolean recursivePublicMethods)
6452cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            throws NoSuchMethodException {
6462cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (name == null) {
6472cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            throw new NullPointerException("name == null");
6482cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
6492cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (parameterTypes == null) {
6502cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            parameterTypes = EmptyArray.CLASS;
6512cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
6522cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        for (Class<?> c : parameterTypes) {
6532cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            if (c == null) {
6542cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                throw new NoSuchMethodException("parameter type is null");
6552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
6562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
6572cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        Method result = recursivePublicMethods ? getPublicMethodRecursive(name, parameterTypes)
6582cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                                               : getDeclaredMethodInternal(name, parameterTypes);
6592cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // Fail if we didn't find the method or it was expected to be public.
6602cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (result == null ||
6612cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            (recursivePublicMethods && !Modifier.isPublic(result.getAccessFlags()))) {
6622cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            throw new NoSuchMethodException(name + " " + Arrays.toString(parameterTypes));
6632cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
6642cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return result;
6652cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
6662cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
6672cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private Method getPublicMethodRecursive(String name, Class<?>[] parameterTypes) {
6682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // search superclasses
6692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
6702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            Method result = c.getDeclaredMethodInternal(name, parameterTypes);
6712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            if (result != null && Modifier.isPublic(result.getAccessFlags())) {
6722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                return result;
6732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
6742cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
6752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // search iftable which has a flattened and uniqued list of interfaces
6762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        Object[] iftable = ifTable;
6772cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (iftable != null) {
6782cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            for (int i = 0; i < iftable.length; i += 2) {
6792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                Class<?> ifc = (Class<?>) iftable[i];
6802cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                Method result = ifc.getPublicMethodRecursive(name, parameterTypes);
6812cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                if (result != null && Modifier.isPublic(result.getAccessFlags())) {
6822cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    return result;
6832cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                }
6842cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
6852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
6862cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return null;
6872cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
6882cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
6892cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
6902cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the method if it is defined by this class; null otherwise. This may return a
6912cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * non-public member.
6922cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
6932cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @param name the method name
6942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @param args the method's parameter types
6952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
6962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private Method getDeclaredMethodInternal(String name, Class<?>[] args) {
6972cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // Covariant return types permit the class to define multiple
6982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // methods with the same name and parameter types. Prefer to
6992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // return a non-synthetic method in such situations. We may
7002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // still return a synthetic method to handle situations like
7012cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // escalated visibility. We never return miranda methods that
7022cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // were synthesized by the VM.
7032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        int skipModifiers = Modifier.MIRANDA | Modifier.SYNTHETIC;
70471dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom        ArtMethod artMethodResult = null;
7056a51140fd83dc16867ca38a4ca2e47cbbf090dfdIan Rogers        if (virtualMethods != null) {
70671dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom            for (ArtMethod m : virtualMethods) {
70771dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                String methodName = ArtMethod.getMethodName(m);
70871dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                if (!name.equals(methodName)) {
70971dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    continue;
71071dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                }
71171dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                if (!ArtMethod.equalMethodParameters(m, args)) {
71271dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    continue;
71371dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                }
71471dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                int modifiers = m.getAccessFlags();
71571dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                if ((modifiers & skipModifiers) == 0) {
71671dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    return new Method(m);
71771dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                }
71871dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                if ((modifiers & Modifier.MIRANDA) == 0) {
71971dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    // Remember as potential result if it's not a miranda method.
72071dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    artMethodResult = m;
7212cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                }
7222cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
7232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
72471dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom        if (artMethodResult == null) {
7256a51140fd83dc16867ca38a4ca2e47cbbf090dfdIan Rogers            if (directMethods != null) {
72671dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                for (ArtMethod m : directMethods) {
72771dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    int modifiers = m.getAccessFlags();
72871dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    if (Modifier.isConstructor(modifiers)) {
72971dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                        continue;
73071dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    }
73171dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    String methodName = ArtMethod.getMethodName(m);
73271dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    if (!name.equals(methodName)) {
73371dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                        continue;
73471dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    }
73571dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    if (!ArtMethod.equalMethodParameters(m, args)) {
73671dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                        continue;
7372cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    }
73871dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    if ((modifiers & skipModifiers) == 0) {
73971dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                        return new Method(m);
74071dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    }
74171dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    // Direct methods cannot be miranda methods,
74271dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    // so this potential result must be synthetic.
74371dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    artMethodResult = m;
7442cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                }
7452cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
7462cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
74771dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom        if (artMethodResult == null) {
74871dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom            return null;
74971dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom        }
75071dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom        return new Method(artMethodResult);
7512cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
7522cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
7532cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
7542cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns an array containing {@code Method} objects for all methods
7552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * declared in the class represented by this {@code Class}. If there are no
7562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * methods or if this {@code Class} represents an array class, a primitive
7572cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * type or void then an empty array is returned.
7582cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
7592cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see #getMethods()
7602cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
7612cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Method[] getDeclaredMethods() {
7622cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        int initial_size = virtualMethods == null ? 0 : virtualMethods.length;
7632cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        initial_size += directMethods == null ? 0 : directMethods.length;
7642cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        ArrayList<Method> methods = new ArrayList<Method>(initial_size);
7654bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette        getDeclaredMethodsUnchecked(false, methods);
7662cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        Method[] result = methods.toArray(new Method[methods.size()]);
7672cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        for (Method m : result) {
7682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            // Throw NoClassDefFoundError if types cannot be resolved.
7692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            m.getReturnType();
7702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            m.getParameterTypes();
7712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
7722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return result;
7732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
7742cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
7752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
7762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
7774bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette     * Populates a list of methods without performing any security or type
7784bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette     * resolution checks first. If no methods exist, the list is not modified.
7794bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette     *
7804bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette     * @param publicOnly Whether to return only public methods.
7814bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette     * @param methods A list to populate with declared methods.
7824bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette     * @hide
7832cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
7844bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette    public void getDeclaredMethodsUnchecked(boolean publicOnly, List<Method> methods) {
7852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (virtualMethods != null) {
78671dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom            for (ArtMethod m : virtualMethods) {
7872cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                int modifiers = m.getAccessFlags();
7882cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                if (!publicOnly || Modifier.isPublic(modifiers)) {
7892cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    // Add non-miranda virtual methods.
7902cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    if ((modifiers & Modifier.MIRANDA) == 0) {
79171dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                        methods.add(new Method(m));
7922cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    }
7932cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                }
7942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
7952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
7962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (directMethods != null) {
79771dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom            for (ArtMethod m : directMethods) {
7982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                int modifiers = m.getAccessFlags();
7992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                if (!publicOnly || Modifier.isPublic(modifiers)) {
8002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    // Add non-constructor direct/static methods.
80171dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    if (!Modifier.isConstructor(modifiers)) {
80271dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                        methods.add(new Method(m));
8032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    }
8042cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                }
8052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
8062cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
8072cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
8082cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
8092cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
8102cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns an array containing {@code Method} objects for all public methods
8112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * for the class C represented by this {@code Class}. Methods may be
8122cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * declared in C, the interfaces it implements or in the superclasses of C.
8132cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * The elements in the returned array are in no particular order.
8142cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
8152cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * <p>If there are no public methods or if this {@code Class} represents a
8162cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * primitive type or {@code void} then an empty array is returned.
8172cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
8182cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see #getDeclaredMethods()
8192cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
8202cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Method[] getMethods() {
8212cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        List<Method> methods = new ArrayList<Method>();
8222cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        getPublicMethodsInternal(methods);
8232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        /*
8242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom         * Remove duplicate methods defined by superclasses and
8252cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom         * interfaces, preferring to keep methods declared by derived
8262cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom         * types.
8272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom         */
8282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        CollectionUtils.removeDuplicates(methods, Method.ORDER_BY_SIGNATURE);
8292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return methods.toArray(new Method[methods.size()]);
8302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
8312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
8322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
8332cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Populates {@code result} with public methods defined by this class, its
8342cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * superclasses, and all implemented interfaces, including overridden methods.
8352cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
8362cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private void getPublicMethodsInternal(List<Method> result) {
8374bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette        getDeclaredMethodsUnchecked(true, result);
8382cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (!isInterface()) {
8392cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            // Search superclasses, for interfaces don't search java.lang.Object.
8402cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            for (Class<?> c = superClass; c != null; c = c.superClass) {
8414bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette                c.getDeclaredMethodsUnchecked(true, result);
8422cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
8432cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
8442cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // Search iftable which has a flattened and uniqued list of interfaces.
8452cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        Object[] iftable = ifTable;
8462cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (iftable != null) {
8472cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            for (int i = 0; i < iftable.length; i += 2) {
8482cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                Class<?> ifc = (Class<?>) iftable[i];
8494bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette                ifc.getDeclaredMethodsUnchecked(true, result);
8502cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
8512cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
8522cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
8532cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
8542cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
8552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the annotations that are directly defined on the class
8562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * represented by this {@code Class}. Annotations that are inherited are not
8572cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * included in the result. If there are no annotations at all, an empty
8582cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * array is returned.
8592cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
8602cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see #getAnnotations()
8612cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
8622cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    @Override public Annotation[] getDeclaredAnnotations() {
8632cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        List<Annotation> result = AnnotationAccess.getDeclaredAnnotations(this);
8642cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return result.toArray(new Annotation[result.size()]);
8652cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
8662cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
8672cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
8682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns an array containing {@code Class} objects for all classes,
8692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * interfaces, enums and annotations that are members of this class.
8702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
8712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Class<?>[] getDeclaredClasses() {
8722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return AnnotationAccess.getMemberClasses(this);
8732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
8742cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
8752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
8762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns a {@code Field} object for the field with the given name
8772cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * which is declared in the class represented by this {@code Class}.
8782cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
8792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws NoSuchFieldException if the requested field can not be found.
8802cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see #getField(String)
8812cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
8822cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Field getDeclaredField(String name) throws NoSuchFieldException {
8832cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (name == null) {
8842cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            throw new NullPointerException("name == null");
8852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
8862cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        Field result = getDeclaredFieldInternal(name);
8872cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (result == null) {
8882cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            throw new NoSuchFieldException(name);
8892cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else {
8902cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            result.getType();  // Throw NoClassDefFoundError if type cannot be resolved.
8912cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
8922cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return result;
8932cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
8942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
8952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
8962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns an array containing {@code Field} objects for all fields declared
8972cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * in the class represented by this {@code Class}. If there are no fields or
8982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * if this {@code Class} represents an array class, a primitive type or void
8992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * then an empty array is returned.
9002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
9012cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see #getFields()
9022cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
9032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Field[] getDeclaredFields() {
9042cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        int initial_size = sFields == null ? 0 : sFields.length;
9052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        initial_size += iFields == null ? 0 : iFields.length;
9062cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        ArrayList<Field> fields = new ArrayList(initial_size);
9074bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette        getDeclaredFieldsUnchecked(false, fields);
9082cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        Field[] result = fields.toArray(new Field[fields.size()]);
9092cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        for (Field f : result) {
9102cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            f.getType();  // Throw NoClassDefFoundError if type cannot be resolved.
9112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
9122cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return result;
9132cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
9142cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
9154bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette    /**
9164bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette     * Populates a list of fields without performing any security or type
9174bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette     * resolution checks first. If no fields exist, the list is not modified.
9184bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette     *
9194bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette     * @param publicOnly Whether to return only public fields.
9204bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette     * @param fields A list to populate with declared fields.
9214bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette     * @hide
9224bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette     */
9234bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette    public void getDeclaredFieldsUnchecked(boolean publicOnly, List<Field> fields) {
9242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (iFields != null) {
92571dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom            for (ArtField f : iFields) {
92671dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                if (!publicOnly || Modifier.isPublic(f.getAccessFlags())) {
92771dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    fields.add(new Field(f));
9282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                }
9292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
9302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
9312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (sFields != null) {
93271dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom            for (ArtField f : sFields) {
93371dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                if (!publicOnly || Modifier.isPublic(f.getAccessFlags())) {
93471dc4f7d4829335f7aba5414b43d16cd316ba22fBrian Carlstrom                    fields.add(new Field(f));
9352cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                }
9362cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
9372cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
9382cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
9392cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
9402cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
9412cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the field if it is defined by this class; null otherwise. This
9422cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * may return a non-public member.
9432cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
9442cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private Field getDeclaredFieldInternal(String name) {
9455346a96c353933579db184a8433fc0cc1e076950Narayan Kamath
9462cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (iFields != null) {
9475346a96c353933579db184a8433fc0cc1e076950Narayan Kamath            final ArtField matched = findByName(name, iFields);
9485346a96c353933579db184a8433fc0cc1e076950Narayan Kamath            if (matched != null) {
9495346a96c353933579db184a8433fc0cc1e076950Narayan Kamath                return new Field(matched);
9502cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
9512cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
9522cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (sFields != null) {
9535346a96c353933579db184a8433fc0cc1e076950Narayan Kamath            final ArtField matched = findByName(name, sFields);
9545346a96c353933579db184a8433fc0cc1e076950Narayan Kamath            if (matched != null) {
9555346a96c353933579db184a8433fc0cc1e076950Narayan Kamath                return new Field(matched);
9565346a96c353933579db184a8433fc0cc1e076950Narayan Kamath            }
9575346a96c353933579db184a8433fc0cc1e076950Narayan Kamath        }
9585346a96c353933579db184a8433fc0cc1e076950Narayan Kamath
9595346a96c353933579db184a8433fc0cc1e076950Narayan Kamath        return null;
9605346a96c353933579db184a8433fc0cc1e076950Narayan Kamath    }
9615346a96c353933579db184a8433fc0cc1e076950Narayan Kamath
9625346a96c353933579db184a8433fc0cc1e076950Narayan Kamath    /**
9635346a96c353933579db184a8433fc0cc1e076950Narayan Kamath     * Performs a binary search through {@code fields} for a field whose name
9645346a96c353933579db184a8433fc0cc1e076950Narayan Kamath     * is {@code name}. Returns {@code null} if no matching field exists.
9655346a96c353933579db184a8433fc0cc1e076950Narayan Kamath     */
9665346a96c353933579db184a8433fc0cc1e076950Narayan Kamath    private static ArtField findByName(String name, ArtField[] fields) {
9675346a96c353933579db184a8433fc0cc1e076950Narayan Kamath        int low = 0, high = fields.length - 1;
9685346a96c353933579db184a8433fc0cc1e076950Narayan Kamath        while (low <= high) {
9695346a96c353933579db184a8433fc0cc1e076950Narayan Kamath            final int mid = (low + high) >>> 1;
9705346a96c353933579db184a8433fc0cc1e076950Narayan Kamath            final ArtField f = fields[mid];
9715346a96c353933579db184a8433fc0cc1e076950Narayan Kamath            final int result = f.getName().compareTo(name);
9725346a96c353933579db184a8433fc0cc1e076950Narayan Kamath            if (result < 0) {
9735346a96c353933579db184a8433fc0cc1e076950Narayan Kamath                low = mid + 1;
9745346a96c353933579db184a8433fc0cc1e076950Narayan Kamath            } else if (result == 0) {
9755346a96c353933579db184a8433fc0cc1e076950Narayan Kamath                return f;
9765346a96c353933579db184a8433fc0cc1e076950Narayan Kamath            } else {
9775346a96c353933579db184a8433fc0cc1e076950Narayan Kamath                high = mid - 1;
9782cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
9792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
9805346a96c353933579db184a8433fc0cc1e076950Narayan Kamath
9812cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return null;
9822cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
9832cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
9842cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
9852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the class that this class is a member of, or {@code null} if this
9862cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * class is a top-level class, a primitive, an array, or defined within a
9872cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * method or constructor.
9882cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
9892cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Class<?> getDeclaringClass() {
9904583b2cee94e9582a6c7a1d715f4896073d03badBrian Carlstrom        if (AnnotationAccess.isAnonymousClass(this)) {
9914583b2cee94e9582a6c7a1d715f4896073d03badBrian Carlstrom            return null;
9924583b2cee94e9582a6c7a1d715f4896073d03badBrian Carlstrom        }
99396caa8ec10a5d64d804a9ed3897c9a34c8626239Brian Carlstrom        return AnnotationAccess.getEnclosingClass(this);
9942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
9952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
9962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
9972cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the class enclosing this class. For most classes this is the same
9982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * as the {@link #getDeclaringClass() declaring class}. For classes defined
9992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * within a method or constructor (typically anonymous inner classes), this
10002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * is the declaring class of that member.
10012cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
10022cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Class<?> getEnclosingClass() {
10032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        Class<?> declaringClass = getDeclaringClass();
10042cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (declaringClass != null) {
10052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return declaringClass;
10062cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
10072cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        AccessibleObject member = AnnotationAccess.getEnclosingMethodOrConstructor(this);
100896caa8ec10a5d64d804a9ed3897c9a34c8626239Brian Carlstrom        if (member != null)  {
100996caa8ec10a5d64d804a9ed3897c9a34c8626239Brian Carlstrom            return ((Member) member).getDeclaringClass();
101096caa8ec10a5d64d804a9ed3897c9a34c8626239Brian Carlstrom        }
101196caa8ec10a5d64d804a9ed3897c9a34c8626239Brian Carlstrom        return AnnotationAccess.getEnclosingClass(this);
10122cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
10132cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
10142cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
10152cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the enclosing {@code Constructor} of this {@code Class}, if it is an
10162cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * anonymous or local/automatic class; otherwise {@code null}.
10172cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
10182cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Constructor<?> getEnclosingConstructor() {
10192cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (classNameImpliesTopLevel()) {
10202cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return null;
10212cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
10222cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        AccessibleObject result = AnnotationAccess.getEnclosingMethodOrConstructor(this);
10232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return result instanceof Constructor ? (Constructor<?>) result : null;
10242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
10252cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
10262cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
10272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the enclosing {@code Method} of this {@code Class}, if it is an
10282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * anonymous or local/automatic class; otherwise {@code null}.
10292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
10302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Method getEnclosingMethod() {
10312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (classNameImpliesTopLevel()) {
10322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return null;
10332cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
10342cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        AccessibleObject result = AnnotationAccess.getEnclosingMethodOrConstructor(this);
10352cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return result instanceof Method ? (Method) result : null;
10362cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
10372cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
10382cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
10392cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns true if this class is definitely a top level class, or false if
10402cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * a more expensive check like {@link #getEnclosingClass()} is necessary.
10412cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
10422cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * <p>This is a hack that exploits an implementation detail of all Java
10432cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * language compilers: generated names always contain "$". As it is possible
10442cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * for a top level class to be named with a "$", a false result <strong>does
10452cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * not</strong> indicate that this isn't a top-level class.
10462cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
10472cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private boolean classNameImpliesTopLevel() {
10482cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return !getName().contains("$");
10492cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
10502cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
10512cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
10522cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the {@code enum} constants associated with this {@code Class}.
10532cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns {@code null} if this {@code Class} does not represent an {@code
10542cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * enum} type.
10552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
10562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    @SuppressWarnings("unchecked") // we only cast after confirming that this class is an enum
10572cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public T[] getEnumConstants() {
10582cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (!isEnum()) {
10592cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return null;
10602cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
10612cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return (T[]) Enum.getSharedConstants((Class) this).clone();
10622cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
10632cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
10642cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
10652cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns a {@code Field} object which represents the public field with the
10662cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * given name. This method first searches the class C represented by
10672cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * this {@code Class}, then the interfaces implemented by C and finally the
10682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * superclasses of C.
10692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
10702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws NoSuchFieldException
10712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if the field cannot be found.
10722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see #getDeclaredField(String)
10732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
10742cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Field getField(String name) throws NoSuchFieldException {
10752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (name == null) {
10762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            throw new NullPointerException("name == null");
10772cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
10782cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        Field result = getPublicFieldRecursive(name);
10792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (result == null) {
10802cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            throw new NoSuchFieldException(name);
10812cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else {
10822cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            result.getType();  // Throw NoClassDefFoundError if type cannot be resolved.
10832cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
10842cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return result;
10852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
10862cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
10872cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private Field getPublicFieldRecursive(String name) {
10882cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // search superclasses
10892cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        for (Class<?> c = this; c != null; c = c.superClass) {
10902cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            Field result = c.getDeclaredFieldInternal(name);
10912cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) {
10922cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                return result;
10932cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
10942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
10952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
10962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // search iftable which has a flattened and uniqued list of interfaces
10972cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (ifTable != null) {
10982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            for (int i = 0; i < ifTable.length; i += 2) {
10992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                Class<?> ifc = (Class<?>) ifTable[i];
11002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                Field result = ifc.getPublicFieldRecursive(name);
11012cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) {
11022cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    return result;
11032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                }
11042cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
11052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
11062cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
11072cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return null;
11082cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
11092cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
11102cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
11112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns an array containing {@code Field} objects for all public fields
11122cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * for the class C represented by this {@code Class}. Fields may be declared
11132cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * in C, the interfaces it implements or in the superclasses of C. The
11142cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * elements in the returned array are in no particular order.
11152cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
11162cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * <p>If there are no public fields or if this class represents an array class,
11172cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * a primitive type or {@code void} then an empty array is returned.
11182cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
11192cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see #getDeclaredFields()
11202cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
11212cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Field[] getFields() {
11222cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        List<Field> fields = new ArrayList<Field>();
11232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        getPublicFieldsRecursive(fields);
11242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        Field[] result = fields.toArray(new Field[fields.size()]);
11252cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        for (Field f : result) {
11262cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            f.getType();  // Throw NoClassDefFoundError if type cannot be resolved.
11272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
11282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return result;
11292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
11302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
11312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
11322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Populates {@code result} with public fields defined by this class, its
11332cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * superclasses, and all implemented interfaces.
11342cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
11352cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private void getPublicFieldsRecursive(List<Field> result) {
11362cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // search superclasses
11372cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        for (Class<?> c = this; c != null; c = c.superClass) {
11384bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette            c.getDeclaredFieldsUnchecked(true, result);
11392cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
11402cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
11412cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // search iftable which has a flattened and uniqued list of interfaces
11422cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        Object[] iftable = ifTable;
11432cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (iftable != null) {
11442cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            for (int i = 0; i < iftable.length; i += 2) {
11452cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                Class<?> ifc = (Class<?>) iftable[i];
11464bde7d71a45ca7d79b53d0770dc8cd6cd5469a76Alan Viverette                ifc.getDeclaredFieldsUnchecked(true, result);
11472cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
11482cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
11492cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
11502cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
11512cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
11522cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the {@link Type}s of the interfaces that this {@code Class} directly
11532cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * implements. If the {@code Class} represents a primitive type or {@code
11542cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * void} then an empty array is returned.
11552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
11562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Type[] getGenericInterfaces() {
1157a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        Type[] result;
1158a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        synchronized (Caches.genericInterfaces) {
1159a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers            result = Caches.genericInterfaces.get(this);
1160a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers            if (result == null) {
1161a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                String annotationSignature = AnnotationAccess.getSignature(this);
1162a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                if (annotationSignature == null) {
1163a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                    result = getInterfaces();
1164a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                } else {
1165a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                    GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
1166a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                    parser.parseForClass(this, annotationSignature);
1167a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                    result = Types.getTypeArray(parser.interfaceTypes, false);
1168a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                }
1169a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                Caches.genericInterfaces.put(this, result);
1170a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers            }
1171d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers        }
1172a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        return (result.length == 0) ? result : result.clone();
11732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
11742cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
11752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
11762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the {@code Type} that represents the superclass of this {@code
11772cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * class}.
11782cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
11792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Type getGenericSuperclass() {
1180d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers        Type genericSuperclass = getSuperclass();
11813b8c8cba4defe9049aca66d505e509395e5485f5Narayan Kamath        // This method is specified to return null for all cases where getSuperclass
11823b8c8cba4defe9049aca66d505e509395e5485f5Narayan Kamath        // returns null, i.e, for primitives, interfaces, void and java.lang.Object.
11833b8c8cba4defe9049aca66d505e509395e5485f5Narayan Kamath        if (genericSuperclass == null) {
11843b8c8cba4defe9049aca66d505e509395e5485f5Narayan Kamath            return null;
11853b8c8cba4defe9049aca66d505e509395e5485f5Narayan Kamath        }
11863b8c8cba4defe9049aca66d505e509395e5485f5Narayan Kamath
1187d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers        String annotationSignature = AnnotationAccess.getSignature(this);
1188d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers        if (annotationSignature != null) {
1189d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers            GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
1190d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers            parser.parseForClass(this, annotationSignature);
1191d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers            genericSuperclass = parser.superclassType;
1192d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers        }
1193d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers        return Types.getType(genericSuperclass);
11942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
11952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
11962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
11972cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns an array of {@code Class} objects that match the interfaces
11982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * in the {@code implements} declaration of the class represented
11992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * by this {@code Class}. The order of the elements in the array is
12002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * identical to the order in the original class declaration. If the class
12012cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * does not implement any interfaces, an empty array is returned.
12022cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
12032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * <p>This method only returns directly-implemented interfaces, and does not
12042cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * include interfaces implemented by superclasses or superinterfaces of any
12052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * implemented interfaces.
12062cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
12072cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Class<?>[] getInterfaces() {
12082cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (isArray()) {
12092cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return new Class<?>[] { Cloneable.class, Serializable.class };
12102cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else if (isProxy()) {
12112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return getProxyInterfaces();
12122cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
1213a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        Dex dex = getDex();
1214a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        if (dex == null) {
1215a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers            return EmptyArray.CLASS;
1216a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        }
1217a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        short[] interfaces = dex.interfaceTypeIndicesFromClassDefIndex(dexClassDefIndex);
1218a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        Class<?>[] result = new Class<?>[interfaces.length];
1219a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        for (int i = 0; i < interfaces.length; i++) {
1220a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers            result[i] = getDexCacheType(dex, interfaces[i]);
1221a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        }
1222a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        return result;
12232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
12242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
12252cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    // Returns the interfaces that this proxy class directly implements.
12262cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private native Class<?>[] getProxyInterfaces();
12272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
12282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
12292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns an integer that represents the modifiers of the class represented
12302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * by this {@code Class}. The returned value is a combination of bits
12312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * defined by constants in the {@link Modifier} class.
12322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
12332cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public int getModifiers() {
123478728ebce868f5949739e6e204e3e0fbf0356f8dElliott Hughes        // Array classes inherit modifiers from their component types, but in the case of arrays
123578728ebce868f5949739e6e204e3e0fbf0356f8dElliott Hughes        // of an inner class, the class file may contain "fake" access flags because it's not valid
123678728ebce868f5949739e6e204e3e0fbf0356f8dElliott Hughes        // for a top-level class to private, say. The real access flags are stored in the InnerClass
123778728ebce868f5949739e6e204e3e0fbf0356f8dElliott Hughes        // attribute, so we need to make sure we drill down to the inner class: the accessFlags
123878728ebce868f5949739e6e204e3e0fbf0356f8dElliott Hughes        // field is not the value we want to return, and the synthesized array class does not itself
123978728ebce868f5949739e6e204e3e0fbf0356f8dElliott Hughes        // have an InnerClass attribute. https://code.google.com/p/android/issues/detail?id=56267
124078728ebce868f5949739e6e204e3e0fbf0356f8dElliott Hughes        if (isArray()) {
124178728ebce868f5949739e6e204e3e0fbf0356f8dElliott Hughes            int componentModifiers = getComponentType().getModifiers();
124278728ebce868f5949739e6e204e3e0fbf0356f8dElliott Hughes            if ((componentModifiers & Modifier.INTERFACE) != 0) {
124378728ebce868f5949739e6e204e3e0fbf0356f8dElliott Hughes                componentModifiers &= ~(Modifier.INTERFACE | Modifier.STATIC);
124478728ebce868f5949739e6e204e3e0fbf0356f8dElliott Hughes            }
124578728ebce868f5949739e6e204e3e0fbf0356f8dElliott Hughes            return Modifier.ABSTRACT | Modifier.FINAL | componentModifiers;
124678728ebce868f5949739e6e204e3e0fbf0356f8dElliott Hughes        }
12472cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        int JAVA_FLAGS_MASK = 0xffff;
12482cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        int modifiers = AnnotationAccess.getInnerClassFlags(this, accessFlags & JAVA_FLAGS_MASK);
12492cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return modifiers & JAVA_FLAGS_MASK;
12502cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
12512cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
12522cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
12532cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the name of the class represented by this {@code Class}. For a
12542cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * description of the format which is used, see the class definition of
12552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * {@link Class}.
12562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
12572cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public String getName() {
12582cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        String result = name;
12592cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return (result == null) ? (name = getNameNative()) : result;
12602cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
12612cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
12622cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private native String getNameNative();
12632cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
12642cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
12652cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the simple name of the class represented by this {@code Class} as
12662cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * defined in the source code. If there is no name (that is, the class is
12672cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * anonymous) then an empty string is returned. If the receiver is an array
12682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * then the name of the underlying type with square braces appended (for
12692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * example {@code "Integer[]"}) is returned.
12702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
12712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @return the simple name of the class represented by this {@code Class}.
12722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
12732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public String getSimpleName() {
12742cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (isArray()) {
12752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return getComponentType().getSimpleName() + "[]";
12762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
12772cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
12782cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (isAnonymousClass()) {
12792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return "";
12802cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
12812cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
12822cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (isMemberClass() || isLocalClass()) {
12832cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return getInnerClassName();
12842cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
12852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
12862cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        String name = getName();
12872cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        int dot = name.lastIndexOf('.');
12882cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (dot != -1) {
12892cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return name.substring(dot + 1);
12902cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
12912cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
12922cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return name;
12932cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
12942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
12952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
12962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the simple name of a member or local class, or null otherwise.
12972cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
12982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private String getInnerClassName() {
12992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return AnnotationAccess.getInnerClassName(this);
13002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
13012cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
13022cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
13032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns null.
13042cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
13052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public ProtectionDomain getProtectionDomain() {
13062cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return null;
13072cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
13082cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
13092cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
13102cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the URL of the given resource, or null if the resource is not found.
13112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * The mapping between the resource name and the URL is managed by the class' class loader.
13122cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
13132cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see ClassLoader
13142cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
13152cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public URL getResource(String resourceName) {
13162cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // Get absolute resource name, but without the leading slash
13172cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (resourceName.startsWith("/")) {
13182cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            resourceName = resourceName.substring(1);
13192cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else {
13202cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            String pkg = getName();
13212cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            int dot = pkg.lastIndexOf('.');
13222cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            if (dot != -1) {
13232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                pkg = pkg.substring(0, dot).replace('.', '/');
13242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            } else {
13252cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                pkg = "";
13262cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
13272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
13282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            resourceName = pkg + "/" + resourceName;
13292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
13302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
13312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // Delegate to proper class loader
13322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        ClassLoader loader = getClassLoader();
13332cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (loader != null) {
13342cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return loader.getResource(resourceName);
13352cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else {
13362cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return ClassLoader.getSystemResource(resourceName);
13372cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
13382cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
13392cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
13402cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
13412cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns a read-only stream for the contents of the given resource, or null if the resource
13422cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * is not found.
13432cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * The mapping between the resource name and the stream is managed by the class' class loader.
13442cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
13452cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @see ClassLoader
13462cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
13472cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public InputStream getResourceAsStream(String resourceName) {
13482cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // Get absolute resource name, but without the leading slash
13492cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (resourceName.startsWith("/")) {
13502cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            resourceName = resourceName.substring(1);
13512cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else {
13522cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            String pkg = getName();
13532cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            int dot = pkg.lastIndexOf('.');
13542cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            if (dot != -1) {
13552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                pkg = pkg.substring(0, dot).replace('.', '/');
13562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            } else {
13572cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                pkg = "";
13582cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
13592cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
13602cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            resourceName = pkg + "/" + resourceName;
13612cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
13622cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
13632cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // Delegate to proper class loader
13642cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        ClassLoader loader = getClassLoader();
13652cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (loader != null) {
13662cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return loader.getResourceAsStream(resourceName);
13672cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else {
13682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return ClassLoader.getSystemResourceAsStream(resourceName);
13692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
13702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
13712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
13722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
13732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns null. (On Android, a {@code ClassLoader} can load classes from multiple dex files.
13742cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * All classes from any given dex file will have the same signers, but different dex
13752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * files may have different signers. This does not fit well with the original
13762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * {@code ClassLoader}-based model of {@code getSigners}.)
13772cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
13782cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Object[] getSigners() {
13792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // See http://code.google.com/p/android/issues/detail?id=1766.
13802cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return null;
13812cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
13822cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
13832cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
13842cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the {@code Class} object which represents the superclass of the
13852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * class represented by this {@code Class}. If this {@code Class} represents
13862cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * the {@code Object} class, a primitive type, an interface or void then the
13872cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * method returns {@code null}. If this {@code Class} represents an array
13882cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * class then the {@code Object} class is returned.
13892cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
13902cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Class<? super T> getSuperclass() {
13912cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom      // For interfaces superClass is Object (which agrees with the JNI spec)
13922cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom      // but not with the expected behavior here.
13932cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom      if (isInterface()) {
13942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return null;
13952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom      } else {
13962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return superClass;
13972cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom      }
13982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
13992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
14002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
14012cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns an array containing {@code TypeVariable} objects for type
14022cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * variables declared by the generic class represented by this {@code
14032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Class}. Returns an empty array if the class is not generic.
14042cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
14052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    @SuppressWarnings("unchecked")
14062cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    @Override public synchronized TypeVariable<Class<T>>[] getTypeParameters() {
1407d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers        String annotationSignature = AnnotationAccess.getSignature(this);
1408d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers        if (annotationSignature == null) {
1409d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers            return EmptyArray.TYPE_VARIABLE;
1410d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers        }
14112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
1412d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers        parser.parseForClass(this, annotationSignature);
1413d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers        return parser.formalTypeParameters;
14142cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
14152cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
14162cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
14172cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Tests whether this {@code Class} represents an annotation class.
14182cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
14192cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public boolean isAnnotation() {
14202cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        final int ACC_ANNOTATION = 0x2000;  // not public in reflect.Modifier
14212cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return (accessFlags & ACC_ANNOTATION) != 0;
14222cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
14232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
14242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
14252cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return AnnotationAccess.isAnnotationPresent(this, annotationType);
14262cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
14272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
14282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
14292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Tests whether the class represented by this {@code Class} is
14302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * anonymous.
14312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
14322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public boolean isAnonymousClass() {
14332cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return AnnotationAccess.isAnonymousClass(this);
14342cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
14352cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
14362cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
14372cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Tests whether the class represented by this {@code Class} is an array class.
14382cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
14392cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public boolean isArray() {
14402cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return getComponentType() != null;
14412cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
14422cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
14432cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
14442cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Is this a runtime created proxy class?
14452cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
14462cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @hide
14472cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
14482cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public boolean isProxy() {
14492cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return (accessFlags & 0x00040000) != 0;
14502cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
14512cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
14522cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
14532cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Can {@code c}  be assigned to this class? For example, String can be assigned to Object
14542cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * (by an upcast), however, an Object cannot be assigned to a String as a potentially exception
14552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * throwing downcast would be necessary. Similarly for interfaces, a class that implements (or
14562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * an interface that extends) another can be assigned to its parent, but not vice-versa. All
14572cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Classes may assign to themselves. Classes for primitive types may not assign to each other.
14582cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
14592cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @param c the class to check.
14602cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @return {@code true} if {@code c} can be assigned to the class
14612cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *         represented by this {@code Class}; {@code false} otherwise.
14622cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws NullPointerException if {@code c} is {@code null}.
14632cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
14642cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public boolean isAssignableFrom(Class<?> c) {
14652cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (this == c) {
14662cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return true;  // Can always assign to things of the same type.
14672cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else if (this == Object.class) {
14682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return !c.isPrimitive();  // Can assign any reference to java.lang.Object.
14692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else if (isArray()) {
14702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return c.isArray() && componentType.isAssignableFrom(c.componentType);
14712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else if (isInterface()) {
14722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            // Search iftable which has a flattened and uniqued list of interfaces.
14732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            Object[] iftable = c.ifTable;
14742cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            if (iftable != null) {
14752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                for (int i = 0; i < iftable.length; i += 2) {
14762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    Class<?> ifc = (Class<?>) iftable[i];
14772cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    if (ifc == this) {
14782cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                        return true;
14792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    }
14802cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                }
14812cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
14822cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return false;
14832cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else {
14842cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            if (!c.isInterface()) {
14852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                for (c = c.superClass; c != null; c = c.superClass) {
14862cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    if (c == this) {
14872cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                        return true;
14882cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    }
14892cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                }
14902cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
14912cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return false;
14922cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
14932cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
14942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
14952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
14962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Tests whether the class represented by this {@code Class} is an
14972cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * {@code enum}.
14982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
14992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public boolean isEnum() {
1500a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        return (getSuperclass() == Enum.class) && ((accessFlags & 0x4000) != 0);
15012cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
15022cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
15032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
15042cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Tests whether the given object can be cast to the class
15052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * represented by this {@code Class}. This is the runtime version of the
15062cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * {@code instanceof} operator.
15072cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
15082cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @return {@code true} if {@code object} can be cast to the type
15092cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *         represented by this {@code Class}; {@code false} if {@code
15102cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *         object} is {@code null} or cannot be cast.
15112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
15122cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public boolean isInstance(Object object) {
15132cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (object == null) {
15142cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return false;
15152cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
15162cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return isAssignableFrom(object.getClass());
15172cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
15182cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
15192cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
15202cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Tests whether this {@code Class} represents an interface.
15212cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
15222cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public boolean isInterface() {
15232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom      return (accessFlags & Modifier.INTERFACE) != 0;
15242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
15252cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
15262cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
15272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Tests whether the class represented by this {@code Class} is defined
15282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * locally.
15292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
15302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public boolean isLocalClass() {
15312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return !classNameImpliesTopLevel()
15322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                && AnnotationAccess.getEnclosingMethodOrConstructor(this) != null
15332cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                && !isAnonymousClass();
15342cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
15352cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
15362cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
15372cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Tests whether the class represented by this {@code Class} is a member
15382cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * class.
15392cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
15402cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public boolean isMemberClass() {
15412cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return getDeclaringClass() != null;
15422cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
15432cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
15442cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
15452cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Tests whether this {@code Class} represents a primitive type.
15462cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
15472cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public boolean isPrimitive() {
1548c519ec27ba900d5422c5a0d40388fb6620981564Hiroshi Yamauchi      return (primitiveType & 0xFFFF) != 0;
15492cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
15502cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
15512cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
15522cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Tests whether this {@code Class} represents a synthetic type.
15532cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
15542cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public boolean isSynthetic() {
15552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        final int ACC_SYNTHETIC = 0x1000;   // not public in reflect.Modifier
15562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return (accessFlags & ACC_SYNTHETIC) != 0;
15572cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
15582cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
15592cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
15602cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Indicates whether this {@code Class} or its parents override finalize.
15612cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
15622cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @hide
15632cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
15642cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public boolean isFinalizable() {
15652cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom      final int ACC_CLASS_IS_FINALIZABLE = 0x80000000;  // not public in reflect.Modifier
15662cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom      return (accessFlags & ACC_CLASS_IS_FINALIZABLE) != 0;
15672cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
15682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
15692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
15702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns a new instance of the class represented by this {@code Class},
15712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * created by invoking the default (that is, zero-argument) constructor. If
15722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * there is no such constructor, or if the creation fails (either because of
15732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * a lack of available memory or because an exception is thrown by the
15742cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * constructor), an {@code InstantiationException} is thrown. If the default
15752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * constructor exists but is not accessible from the context where this
15762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * method is invoked, an {@code IllegalAccessException} is thrown.
15772cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
15782cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws IllegalAccessException
15792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if the default constructor is not visible.
15802cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws InstantiationException
15812cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if the instance cannot be created.
15822cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
15832cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public T newInstance() throws InstantiationException, IllegalAccessException {
15842cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (isPrimitive() || isInterface() || isArray() || Modifier.isAbstract(accessFlags)) {
15852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            throw new InstantiationException(this + " cannot be instantiated");
15862cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
158796e2e4faf806aa22ca205354c16b04288d51ddbfJeff Hao        Class<?> caller = VMStack.getStackClass1();
158896e2e4faf806aa22ca205354c16b04288d51ddbfJeff Hao        if (!caller.canAccess(this)) {
158996e2e4faf806aa22ca205354c16b04288d51ddbfJeff Hao          throw new IllegalAccessException(this + " is not accessible from " + caller);
159096e2e4faf806aa22ca205354c16b04288d51ddbfJeff Hao        }
15912cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        Constructor<T> init;
15922cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        try {
15932cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            init = getDeclaredConstructor();
15942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } catch (NoSuchMethodException e) {
15952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            InstantiationException t =
15962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                new InstantiationException(this + " has no zero argument constructor");
15972cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            t.initCause(e);
15982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            throw t;
15992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
160096e2e4faf806aa22ca205354c16b04288d51ddbfJeff Hao        if (!caller.canAccessMember(this, init.getAccessFlags())) {
160196e2e4faf806aa22ca205354c16b04288d51ddbfJeff Hao          throw new IllegalAccessException(init + " is not accessible from " + caller);
160296e2e4faf806aa22ca205354c16b04288d51ddbfJeff Hao        }
16032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        try {
1604793b9ef91876cb7bea31ddf74f110ac45302f1ddJeff Hao          return init.newInstance(null, init.isAccessible());
16052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } catch (InvocationTargetException e) {
1606793b9ef91876cb7bea31ddf74f110ac45302f1ddJeff Hao          SneakyThrow.sneakyThrow(e.getCause());
1607793b9ef91876cb7bea31ddf74f110ac45302f1ddJeff Hao          return null;  // Unreachable.
16082cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
16092cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
16102cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
16112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private boolean canAccess(Class<?> c) {
16122cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if(Modifier.isPublic(c.accessFlags)) {
16132cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return true;
16142cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
16152cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return inSamePackage(c);
16162cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
16172cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
16182cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private boolean canAccessMember(Class<?> memberClass, int memberModifiers) {
16192cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (memberClass == this || Modifier.isPublic(memberModifiers)) {
16202cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return true;
16212cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
16222cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (Modifier.isPrivate(memberModifiers)) {
16232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return false;
16242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
16252cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (Modifier.isProtected(memberModifiers)) {
16262cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            for (Class<?> parent = this.superClass; parent != null; parent = parent.superClass) {
16272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                if (parent == memberClass) {
16282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                    return true;
16292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom                }
16302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            }
16312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
16322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return inSamePackage(memberClass);
16332cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
16342cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
16352cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    private boolean inSamePackage(Class<?> c) {
16362cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (classLoader != c.classLoader) {
16372cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return false;
16382cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
16392cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        String packageName1 = getPackageName$();
16402cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        String packageName2 = c.getPackageName$();
16412cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (packageName1 == null) {
16422cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return packageName2 == null;
16432cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else if (packageName2 == null) {
16442cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return false;
16452cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else {
16462cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return packageName1.equals(packageName2);
16472cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
16482cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
16492cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
16502cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    @Override
16512cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public String toString() {
16522cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (isPrimitive()) {
16532cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return getSimpleName();
16542cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else {
16552cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return (isInterface() ? "interface " : "class ") + getName();
16562cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
16572cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
16582cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
16592cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
16602cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the {@code Package} of which the class represented by this
16612cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * {@code Class} is a member. Returns {@code null} if no {@code Package}
16622cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * object was created by the class loader of the class.
16632cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
16642cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public Package getPackage() {
16652cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        // TODO This might be a hack, but the VM doesn't have the necessary info.
16662cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        ClassLoader loader = getClassLoader();
16672cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (loader != null) {
16682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            String packageName = getPackageName$();
16692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return packageName != null ? loader.getPackage(packageName) : null;
16702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
16712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return null;
16722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
16732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
16742cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
16752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the package name of this class. This returns null for classes in
16762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * the default package.
16772cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
16782cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @hide
16792cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
16802cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public String getPackageName$() {
16812cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        String name = getName();
16822cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        int last = name.lastIndexOf('.');
16832cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        return last == -1 ? null : name.substring(0, last);
16842cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
16852cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
16862cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
16872cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Returns the assertion status for the class represented by this {@code
16882cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Class}. Assertion is enabled / disabled based on the class loader,
16892cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * package or class default at runtime.
16902cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
16912cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public boolean desiredAssertionStatus() {
16922cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom      return false;
16932cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
16942cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
16952cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
16962cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Casts this {@code Class} to represent a subclass of the given class.
16972cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * If successful, this {@code Class} is returned; otherwise a {@code
16982cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * ClassCastException} is thrown.
16992cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
17002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws ClassCastException
17012cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if this {@code Class} cannot be cast to the given type.
17022cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
17032cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    @SuppressWarnings("unchecked")
17042cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public <U> Class<? extends U> asSubclass(Class<U> c) {
17052cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (c.isAssignableFrom(this)) {
17062cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return (Class<? extends U>)this;
17072cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
17082cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        String actualClassName = this.getName();
17092cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        String desiredClassName = c.getName();
17102cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        throw new ClassCastException(actualClassName + " cannot be cast to " + desiredClassName);
17112cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
17122cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
17132cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
17142cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * Casts the given object to the type represented by this {@code Class}.
17152cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * If the object is {@code null} then the result is also {@code null}.
17162cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
17172cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @throws ClassCastException
17182cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *             if the object cannot be cast to the given type.
17192cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
17202cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    @SuppressWarnings("unchecked")
17212cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    public T cast(Object obj) {
17222cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        if (obj == null) {
17232cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return null;
17242cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        } else if (this.isInstance(obj)) {
17252cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom            return (T)obj;
17262cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
17272cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        String actualClassName = obj.getClass().getName();
17282cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        String desiredClassName = this.getName();
17292cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        throw new ClassCastException(actualClassName + " cannot be cast to " + desiredClassName);
17302cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
17312cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
17322cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
1733a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     * The class def of this class in its own Dex, or -1 if there is no class def.
17342cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
1735a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     * @hide
1736a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     */
1737a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers    public int getDexClassDefIndex() {
1738a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        return (dexClassDefIndex == 65535) ? -1 : dexClassDefIndex;
1739a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers    }
1740a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers
1741a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers    /**
1742a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     * The type index of this class in its own Dex, or -1 if it is unknown. If a class is referenced
1743a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     * by multiple Dex files, it will have a different type index in each. Dex files support 65534
1744a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers     * type indices, with 65535 representing no index.
17452cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
17462cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @hide
17472cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
1748a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers    public int getDexTypeIndex() {
1749a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        int typeIndex = dexTypeIndex;
1750a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        if (typeIndex != 65535) {
1751a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers            return typeIndex;
1752a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        }
1753a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        synchronized (this) {
1754a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers            typeIndex = dexTypeIndex;
1755a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers            if (typeIndex == 65535) {
1756a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                if (dexClassDefIndex >= 0) {
1757a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                    typeIndex = getDex().typeIndexFromClassDefIndex(dexClassDefIndex);
1758a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                } else {
1759a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                    typeIndex = getDex().findTypeIndex(InternalNames.getInternalName(this));
1760a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                    if (typeIndex < 0) {
1761a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                        typeIndex = -1;
1762a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                    }
1763a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                }
1764a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers                dexTypeIndex = typeIndex;
1765a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers            }
17662cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom        }
1767a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        return typeIndex;
17682cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    }
17692cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom
17702cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom    /**
17712cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * The annotation directory offset of this class in its own Dex, or 0 if it
17722cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * is unknown.
17732cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
17742cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * TODO: 0 is a sentinel that means 'no annotations directory'; this should be -1 if unknown
17752cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     *
17762cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     * @hide
17772cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom     */
1778a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers    public int getDexAnnotationDirectoryOffset() {
1779a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        Dex dex = getDex();
1780a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        if (dex == null) {
1781a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers            return 0;
1782a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        }
1783a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        int classDefIndex = getDexClassDefIndex();
1784a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        if (classDefIndex < 0) {
1785a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers            return 0;
1786a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        }
1787a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        return dex.annotationDirectoryOffsetFromClassDefIndex(classDefIndex);
1788a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers    }
1789d4ec55c4e1acc3c3df937facbd367aff6618536cIan Rogers
1790a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers    private static class Caches {
1791a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        /**
1792a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers         * Cache to avoid frequent recalculation of generic interfaces, which is generally uncommon.
1793a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers         * Sized sufficient to allow ConcurrentHashMapTest to run without recalculating its generic
1794a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers         * interfaces (required to avoid time outs). Validated by running reflection heavy code
1795a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers         * such as applications using Guice-like frameworks.
1796a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers         */
1797a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers        private static final BasicLruCache<Class, Type[]> genericInterfaces
1798a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers            = new BasicLruCache<Class, Type[]>(8);
1799a6e22fc9b70ebe39abd716ce37450bda935c0fb8Ian Rogers    }
18002cf03dc15c40b92634ff606694af5a6e9aa4db09Brian Carlstrom}
1801