1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17/*
18 * Copyright (C) 2006-2007 The Android Open Source Project
19 *
20 * Licensed under the Apache License, Version 2.0 (the "License");
21 * you may not use this file except in compliance with the License.
22 * You may obtain a copy of the License at
23 *
24 *      http://www.apache.org/licenses/LICENSE-2.0
25 *
26 * Unless required by applicable law or agreed to in writing, software
27 * distributed under the License is distributed on an "AS IS" BASIS,
28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29 * See the License for the specific language governing permissions and
30 * limitations under the License.
31 */
32
33package java.lang;
34
35import dalvik.system.VMStack;
36import java.io.InputStream;
37import java.io.Serializable;
38import java.lang.annotation.Annotation;
39import java.lang.annotation.Inherited;
40import java.lang.reflect.AnnotatedElement;
41import java.lang.reflect.Constructor;
42import java.lang.reflect.Field;
43import java.lang.reflect.GenericDeclaration;
44import java.lang.reflect.Member;
45import java.lang.reflect.Method;
46import java.lang.reflect.Modifier;
47import java.lang.reflect.Type;
48import java.lang.reflect.TypeVariable;
49import java.net.URL;
50import java.security.ProtectionDomain;
51import java.util.ArrayList;
52import java.util.Arrays;
53import java.util.Collection;
54import java.util.HashMap;
55import java.util.List;
56import libcore.util.CollectionUtils;
57import libcore.util.EmptyArray;
58import org.apache.harmony.kernel.vm.StringUtils;
59import org.apache.harmony.luni.lang.reflect.GenericSignatureParser;
60import org.apache.harmony.luni.lang.reflect.Types;
61
62/**
63 * The in-memory representation of a Java class. This representation serves as
64 * the starting point for querying class-related information, a process usually
65 * called "reflection". There are basically three types of {@code Class}
66 * instances: those representing real classes and interfaces, those representing
67 * primitive types, and those representing array classes.
68 *
69 * <h4>Class instances representing object types (classes or interfaces)</h4>
70 * <p>
71 * These represent an ordinary class or interface as found in the class
72 * hierarchy. The name associated with these {@code Class} instances is simply
73 * the fully qualified class name of the class or interface that it represents.
74 * In addition to this human-readable name, each class is also associated by a
75 * so-called <em>signature</em>, which is the letter "L", followed by the
76 * class name and a semicolon (";"). The signature is what the runtime system
77 * uses internally for identifying the class (for example in a DEX file).
78 * </p>
79 * <h4>Classes representing primitive types</h4>
80 * <p>
81 * These represent the standard Java primitive types and hence share their
82 * names (for example "int" for the {@code int} primitive type). Although it is
83 * not possible to create new instances based on these {@code Class} instances,
84 * they are still useful for providing reflection information, and as the
85 * component type of array classes. There is one {@code Class} instance for each
86 * primitive type, and their signatures are:
87 * </p>
88 * <ul>
89 * <li>{@code B} representing the {@code byte} primitive type</li>
90 * <li>{@code S} representing the {@code short} primitive type</li>
91 * <li>{@code I} representing the {@code int} primitive type</li>
92 * <li>{@code J} representing the {@code long} primitive type</li>
93 * <li>{@code F} representing the {@code float} primitive type</li>
94 * <li>{@code D} representing the {@code double} primitive type</li>
95 * <li>{@code C} representing the {@code char} primitive type</li>
96 * <li>{@code Z} representing the {@code boolean} primitive type</li>
97 * <li>{@code V} representing void function return values</li>
98 * </ul>
99 * <p>
100 * <h4>Classes representing array classes</h4>
101 * <p>
102 * These represent the classes of Java arrays. There is one such {@code Class}
103 * instance per combination of array leaf component type and arity (number of
104 * dimensions). In this case, the name associated with the {@code Class}
105 * consists of one or more left square brackets (one per dimension in the array)
106 * followed by the signature of the class representing the leaf component type,
107 * which can be either an object type or a primitive type. The signature of a
108 * {@code Class} representing an array type is the same as its name. Examples
109 * of array class signatures are:
110 * </p>
111 * <ul>
112 * <li>{@code [I} representing the {@code int[]} type</li>
113 * <li>{@code [Ljava/lang/String;} representing the {@code String[]} type</li>
114 * <li>{@code [[[C} representing the {@code char[][][]} type (three dimensions!)</li>
115 * </ul>
116 */
117public final class Class<T> implements Serializable, AnnotatedElement, GenericDeclaration, Type {
118
119    private static final long serialVersionUID = 3206093459760846163L;
120
121    /**
122     * Lazily computed name of this class; always prefer calling getName().
123     */
124    private transient String name;
125
126    private Class() {
127        // Prevent this class to be instantiated, instance
128        // should be created by JVM only
129    }
130
131    /**
132     * Get the Signature attribute for this class.  Returns null if not found.
133     */
134    private String getSignatureAttribute() {
135        Object[] annotation = getSignatureAnnotation();
136
137        if (annotation == null) {
138            return null;
139        }
140
141        return StringUtils.combineStrings(annotation);
142    }
143
144    /**
145     * Get the Signature annotation for this class.  Returns null if not found.
146     */
147    native private Object[] getSignatureAnnotation();
148
149    /**
150     * Returns a {@code Class} object which represents the class with the
151     * specified name. The name should be the name of a class as described in
152     * the {@link Class class definition}; however, {@code Class}es representing
153     * primitive types can not be found using this method.
154     * <p>
155     * If the class has not been loaded so far, it is being loaded and linked
156     * first. This is done through either the class loader of the calling class
157     * or one of its parent class loaders. The class is also being initialized,
158     * which means that a possible static initializer block is executed.
159     *
160     * @param className
161     *            the name of the non-primitive-type class to find.
162     * @return the named {@code Class} instance.
163     * @throws ClassNotFoundException
164     *             if the requested class can not be found.
165     * @throws LinkageError
166     *             if an error occurs during linkage
167     * @throws ExceptionInInitializerError
168     *             if an exception occurs during static initialization of a
169     *             class.
170     */
171    public static Class<?> forName(String className) throws ClassNotFoundException {
172        return forName(className, true, VMStack.getCallingClassLoader());
173    }
174
175    /**
176     * Returns a {@code Class} object which represents the class with the
177     * specified name. The name should be the name of a class as described in
178     * the {@link Class class definition}, however {@code Class}es representing
179     * primitive types can not be found using this method. Security rules will
180     * be obeyed.
181     * <p>
182     * If the class has not been loaded so far, it is being loaded and linked
183     * first. This is done through either the specified class loader or one of
184     * its parent class loaders. The caller can also request the class to be
185     * initialized, which means that a possible static initializer block is
186     * executed.
187     *
188     * @param className
189     *            the name of the non-primitive-type class to find.
190     * @param initializeBoolean
191     *            indicates whether the class should be initialized.
192     * @param classLoader
193     *            the class loader to use to load the class.
194     * @return the named {@code Class} instance.
195     * @throws ClassNotFoundException
196     *             if the requested class can not be found.
197     * @throws LinkageError
198     *             if an error occurs during linkage
199     * @throws ExceptionInInitializerError
200     *             if an exception occurs during static initialization of a
201     *             class.
202     */
203    public static Class<?> forName(String className, boolean initializeBoolean,
204            ClassLoader classLoader) throws ClassNotFoundException {
205
206        if (classLoader == null) {
207            classLoader = ClassLoader.getSystemClassLoader();
208        }
209        // Catch an Exception thrown by the underlying native code. It wraps
210        // up everything inside a ClassNotFoundException, even if e.g. an
211        // Error occurred during initialization. This as a workaround for
212        // an ExceptionInInitilaizerError that's also wrapped. It is actually
213        // expected to be thrown. Maybe the same goes for other errors.
214        // Not wrapping up all the errors will break android though.
215        Class<?> result;
216        try {
217            result = classForName(className, initializeBoolean,
218                    classLoader);
219        } catch (ClassNotFoundException e) {
220            Throwable cause = e.getCause();
221            if (cause instanceof ExceptionInInitializerError) {
222                throw (ExceptionInInitializerError) cause;
223            }
224            throw e;
225        }
226        return result;
227    }
228
229    /*
230     * Returns a class by name without any security checks.
231     *
232     * @param className The name of the non-primitive type class to find
233     * @param initializeBoolean A boolean indicating whether the class should be
234     *        initialized
235     * @param classLoader The class loader to use to load the class
236     * @return the named class.
237     * @throws ClassNotFoundException If the class could not be found
238     */
239    static native Class<?> classForName(String className, boolean initializeBoolean,
240            ClassLoader classLoader) throws ClassNotFoundException;
241
242    /**
243     * Returns an array containing {@code Class} objects for all public classes
244     * and interfaces that are members of this class. This includes public
245     * members inherited from super classes and interfaces. If there are no such
246     * class members or if this object represents a primitive type then an array
247     * of length 0 is returned.
248     *
249     * @return the public class members of the class represented by this object.
250     */
251    public Class<?>[] getClasses() {
252        return getFullListOfClasses(true);
253    }
254
255    @Override public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
256        if (annotationType == null) {
257            throw new NullPointerException("annotationType == null");
258        }
259
260        A annotation = getDeclaredAnnotation(annotationType);
261        if (annotation != null) {
262            return annotation;
263        }
264
265        if (annotationType.isAnnotationPresent(Inherited.class)) {
266            for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
267                annotation = sup.getDeclaredAnnotation(annotationType);
268                if (annotation != null) {
269                    return annotation;
270                }
271            }
272        }
273
274        return null;
275    }
276
277    /**
278     * Returns all the annotations of this class. If there are no annotations
279     * then an empty array is returned.
280     *
281     * @return a copy of the array containing this class' annotations.
282     * @see #getDeclaredAnnotations()
283     */
284    public Annotation[] getAnnotations() {
285        /*
286         * We need to get the annotations declared on this class, plus the
287         * annotations from superclasses that have the "@Inherited" annotation
288         * set.  We create a temporary map to use while we accumulate the
289         * annotations and convert it to an array at the end.
290         *
291         * It's possible to have duplicates when annotations are inherited.
292         * We use a Map to filter those out.
293         *
294         * HashMap might be overkill here.
295         */
296        HashMap<Class, Annotation> map = new HashMap<Class, Annotation>();
297        Annotation[] declaredAnnotations = getDeclaredAnnotations();
298
299        for (int i = declaredAnnotations.length-1; i >= 0; --i) {
300            map.put(declaredAnnotations[i].annotationType(), declaredAnnotations[i]);
301        }
302        for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
303            declaredAnnotations = sup.getDeclaredAnnotations();
304            for (int i = declaredAnnotations.length-1; i >= 0; --i) {
305                Class<?> clazz = declaredAnnotations[i].annotationType();
306                if (!map.containsKey(clazz) && clazz.isAnnotationPresent(Inherited.class)) {
307                    map.put(clazz, declaredAnnotations[i]);
308                }
309            }
310        }
311
312        /* convert annotation values from HashMap to array */
313        Collection<Annotation> coll = map.values();
314        return coll.toArray(new Annotation[coll.size()]);
315    }
316
317    /**
318     * Returns the canonical name of this class. If this class does not have a
319     * canonical name as defined in the Java Language Specification, then the
320     * method returns {@code null}.
321     *
322     * @return this class' canonical name, or {@code null} if it does not have a
323     *         canonical name.
324     */
325    public String getCanonicalName() {
326        if (isLocalClass() || isAnonymousClass())
327            return null;
328
329        if (isArray()) {
330            /*
331             * The canonical name of an array type depends on the (existence of)
332             * the component type's canonical name.
333             */
334            String name = getComponentType().getCanonicalName();
335            if (name != null) {
336                return name + "[]";
337            }
338        } else if (isMemberClass()) {
339            /*
340             * The canonical name of an inner class depends on the (existence
341             * of) the declaring class' canonical name.
342             */
343            String name = getDeclaringClass().getCanonicalName();
344            if (name != null) {
345                return name + "." + getSimpleName();
346            }
347        } else {
348            /*
349             * The canonical name of a top-level class or primitive type is
350             * equal to the fully qualified name.
351             */
352            return getName();
353        }
354
355        /*
356         * Other classes don't have a canonical name.
357         */
358        return null;
359    }
360
361    /**
362     * Returns the class loader which was used to load the class represented by
363     * this {@code Class}. Implementations are free to return {@code null} for
364     * classes that were loaded by the bootstrap class loader. The Android
365     * reference implementation, though, returns a reference to an actual
366     * representation of the bootstrap class loader.
367     *
368     * @return the class loader for the represented class.
369     * @see ClassLoader
370     */
371    public ClassLoader getClassLoader() {
372        if (this.isPrimitive()) {
373            return null;
374        }
375
376        ClassLoader loader = getClassLoaderImpl();
377        if (loader == null) {
378            loader = BootClassLoader.getInstance();
379        }
380        return loader;
381    }
382
383    /**
384     * This must be provided by the VM vendor, as it is used by other provided
385     * class implementations in this package. Outside of this class, it is used
386     * by SecurityManager.classLoaderDepth(),
387     * currentClassLoader() and currentLoadedClass(). Return the ClassLoader for
388     * this Class without doing any security checks. The bootstrap ClassLoader
389     * is returned, unlike getClassLoader() which returns null in place of the
390     * bootstrap ClassLoader.
391     *
392     * @return the ClassLoader
393     */
394    ClassLoader getClassLoaderImpl() {
395        ClassLoader loader = getClassLoader(this);
396        return loader == null ? BootClassLoader.getInstance() : loader;
397    }
398
399    /*
400     * Returns the defining class loader for the given class.
401     *
402     * @param clazz the class the class loader of which we want
403     * @return the class loader
404     */
405    private static native ClassLoader getClassLoader(Class<?> clazz);
406
407    /**
408     * Returns a {@code Class} object which represents the component type if
409     * this class represents an array type. Returns {@code null} if this class
410     * does not represent an array type. The component type of an array type is
411     * the type of the elements of the array.
412     *
413     * @return the component type of this class.
414     */
415    public native Class<?> getComponentType();
416
417    /**
418     * Returns a {@code Constructor} object which represents the public
419     * constructor matching the specified parameter types.
420     *
421     * @param parameterTypes
422     *            the parameter types of the requested constructor.
423     *            {@code (Class[]) null} is equivalent to the empty array.
424     * @return the constructor described by {@code parameterTypes}.
425     * @throws NoSuchMethodException
426     *             if the constructor can not be found.
427     * @see #getDeclaredConstructor(Class[])
428     */
429    @SuppressWarnings("unchecked")
430    public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException {
431        return (Constructor) getConstructorOrMethod("<init>", false, true, parameterTypes);
432    }
433
434    /**
435     * Returns a constructor or method with the specified name.
436     *
437     * @param name the method name, or "<init>" to return a constructor.
438     * @param recursive true to search supertypes.
439     */
440    private Member getConstructorOrMethod(String name, boolean recursive,
441            boolean publicOnly, Class<?>[] parameterTypes) throws NoSuchMethodException {
442        if (recursive && !publicOnly) {
443            throw new AssertionError(); // can't lookup non-public members recursively
444        }
445        if (name == null) {
446            throw new NullPointerException("name == null");
447        }
448        if (parameterTypes == null) {
449            parameterTypes = EmptyArray.CLASS;
450        }
451        for (Class<?> c : parameterTypes) {
452            if (c == null) {
453                throw new NoSuchMethodException("parameter type is null");
454            }
455        }
456        Member result = recursive
457                ? getPublicConstructorOrMethodRecursive(name, parameterTypes)
458                : Class.getDeclaredConstructorOrMethod(this, name, parameterTypes);
459        if (result == null || publicOnly && (result.getModifiers() & Modifier.PUBLIC) == 0) {
460            throw new NoSuchMethodException(name + " " + Arrays.toString(parameterTypes));
461        }
462        return result;
463    }
464
465    private Member getPublicConstructorOrMethodRecursive(String name, Class<?>[] parameterTypes) {
466        // search superclasses
467        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
468            Member result = Class.getDeclaredConstructorOrMethod(c, name, parameterTypes);
469            if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) {
470                return result;
471            }
472        }
473
474        // search implemented interfaces
475        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
476            for (Class<?> ifc : c.getInterfaces()) {
477                Member result = ifc.getPublicConstructorOrMethodRecursive(name, parameterTypes);
478                if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) {
479                    return result;
480                }
481            }
482        }
483
484        return null;
485    }
486
487    /**
488     * Returns an array containing {@code Constructor} objects for all public
489     * constructors for the class represented by this {@code Class}. If there
490     * are no public constructors or if this {@code Class} represents an array
491     * class, a primitive type or void then an empty array is returned.
492     *
493     * @return an array with the public constructors of the class represented by
494     *         this {@code Class}.
495     * @see #getDeclaredConstructors()
496     */
497    public Constructor<?>[] getConstructors() {
498        return getDeclaredConstructors(this, true);
499    }
500
501    /**
502     * Returns the annotations that are directly defined on the class
503     * represented by this {@code Class}. Annotations that are inherited are not
504     * included in the result. If there are no annotations at all, an empty
505     * array is returned.
506     *
507     * @return a copy of the array containing the annotations defined for the
508     *         class that this {@code Class} represents.
509     * @see #getAnnotations()
510     */
511    native public Annotation[] getDeclaredAnnotations();
512
513    /**
514     * Returns the annotation if it exists.
515     */
516    native private <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass);
517
518    /**
519     * Returns true if the annotation exists.
520     */
521    native private boolean isDeclaredAnnotationPresent(Class<? extends Annotation> annotationClass);
522
523    /**
524     * Returns an array containing {@code Class} objects for all classes and
525     * interfaces that are declared as members of the class which this {@code
526     * Class} represents. If there are no classes or interfaces declared or if
527     * this class represents an array class, a primitive type or void, then an
528     * empty array is returned.
529     *
530     * @return an array with {@code Class} objects for all the classes and
531     *         interfaces that are used in member declarations.
532     */
533    public Class<?>[] getDeclaredClasses() {
534        return getDeclaredClasses(this, false);
535    }
536
537    /*
538     * Returns the list of member classes without performing any security checks
539     * first. This includes the member classes inherited from superclasses. If no
540     * member classes exist at all, an empty array is returned.
541     *
542     * @param publicOnly reflects whether we want only public members or all of them
543     * @return the list of classes
544     */
545    private Class<?>[] getFullListOfClasses(boolean publicOnly) {
546        Class<?>[] result = getDeclaredClasses(this, publicOnly);
547
548        // Traverse all superclasses
549        Class<?> clazz = this.getSuperclass();
550        while (clazz != null) {
551            Class<?>[] temp = getDeclaredClasses(clazz, publicOnly);
552            if (temp.length != 0) {
553                result = arraycopy(new Class[result.length + temp.length], result, temp);
554            }
555
556            clazz = clazz.getSuperclass();
557        }
558
559        return result;
560    }
561
562    /*
563     * Returns the list of member classes of the given class. No security checks
564     * are performed. If no members exist, an empty array is returned.
565     *
566     * @param clazz the class the members of which we want
567     * @param publicOnly reflects whether we want only public member or all of them
568     * @return the class' class members
569     */
570    private static native Class<?>[] getDeclaredClasses(Class<?> clazz, boolean publicOnly);
571
572    /**
573     * Returns a {@code Constructor} object which represents the constructor
574     * matching the specified parameter types that is declared by the class
575     * represented by this {@code Class}.
576     *
577     * @param parameterTypes
578     *            the parameter types of the requested constructor.
579     *            {@code (Class[]) null} is equivalent to the empty array.
580     * @return the constructor described by {@code parameterTypes}.
581     * @throws NoSuchMethodException
582     *             if the requested constructor can not be found.
583     * @see #getConstructor(Class[])
584     */
585    @SuppressWarnings("unchecked")
586    public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
587            throws NoSuchMethodException {
588        return (Constructor) getConstructorOrMethod("<init>", false, false, parameterTypes);
589    }
590
591    /**
592     * Returns an array containing {@code Constructor} objects for all
593     * constructors declared in the class represented by this {@code Class}. If
594     * there are no constructors or if this {@code Class} represents an array
595     * class, a primitive type or void then an empty array is returned.
596     *
597     * @return an array with the constructors declared in the class represented
598     *         by this {@code Class}.
599     * @see #getConstructors()
600     */
601    public Constructor<?>[] getDeclaredConstructors() {
602        return getDeclaredConstructors(this, false);
603    }
604
605    /*
606     * Returns the list of constructors without performing any security checks
607     * first. If no constructors exist, an empty array is returned.
608     *
609     * @param clazz the class of interest
610     * @param publicOnly reflects whether we want only public constructors or all of them
611     * @return the list of constructors
612     */
613    private static native <T> Constructor<T>[] getDeclaredConstructors(
614            Class<T> clazz, boolean publicOnly);
615
616    /**
617     * Returns a {@code Field} object for the field with the specified name
618     * which is declared in the class represented by this {@code Class}.
619     *
620     * @param name the name of the requested field.
621     * @return the requested field in the class represented by this class.
622     * @throws NoSuchFieldException if the requested field can not be found.
623     * @see #getField(String)
624     */
625    public Field getDeclaredField(String name) throws NoSuchFieldException {
626        if (name == null) {
627            throw new NullPointerException("name == null");
628        }
629        Field result = getDeclaredField(this, name);
630        if (result == null) {
631            throw new NoSuchFieldException(name);
632        }
633        return result;
634    }
635
636    /**
637     * Returns an array containing {@code Field} objects for all fields declared
638     * in the class represented by this {@code Class}. If there are no fields or
639     * if this {@code Class} represents an array class, a primitive type or void
640     * then an empty array is returned.
641     *
642     * @return an array with the fields declared in the class represented by
643     *         this class.
644     * @see #getFields()
645     */
646    public Field[] getDeclaredFields() {
647        return getDeclaredFields(this, false);
648    }
649
650    /*
651     * Returns the list of fields without performing any security checks
652     * first. If no fields exist at all, an empty array is returned.
653     *
654     * @param clazz the class of interest
655     * @param publicOnly reflects whether we want only public fields or all of them
656     * @return the list of fields
657     */
658    static native Field[] getDeclaredFields(Class<?> clazz, boolean publicOnly);
659
660    /**
661     * Returns the field if it is defined by {@code clazz}; null otherwise. This
662     * may return a non-public member.
663     */
664    static native Field getDeclaredField(Class<?> clazz, String name);
665
666    /**
667     * Returns a {@code Method} object which represents the method matching the
668     * specified name and parameter types that is declared by the class
669     * represented by this {@code Class}.
670     *
671     * @param name
672     *            the requested method's name.
673     * @param parameterTypes
674     *            the parameter types of the requested method.
675     *            {@code (Class[]) null} is equivalent to the empty array.
676     * @return the method described by {@code name} and {@code parameterTypes}.
677     * @throws NoSuchMethodException
678     *             if the requested constructor can not be found.
679     * @throws NullPointerException
680     *             if {@code name} is {@code null}.
681     * @see #getMethod(String, Class[])
682     */
683    public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
684            throws NoSuchMethodException {
685        Member member = getConstructorOrMethod(name, false, false, parameterTypes);
686        if (member instanceof Constructor) {
687            throw new NoSuchMethodException(name);
688        }
689        return (Method) member;
690    }
691
692    /**
693     * Returns an array containing {@code Method} objects for all methods
694     * declared in the class represented by this {@code Class}. If there are no
695     * methods or if this {@code Class} represents an array class, a primitive
696     * type or void then an empty array is returned.
697     *
698     * @return an array with the methods declared in the class represented by
699     *         this {@code Class}.
700     * @see #getMethods()
701     */
702    public Method[] getDeclaredMethods() {
703        return getDeclaredMethods(this, false);
704    }
705
706    /**
707     * Returns the list of methods without performing any security checks
708     * first. If no methods exist, an empty array is returned.
709     */
710    static native Method[] getDeclaredMethods(Class<?> clazz, boolean publicOnly);
711
712    /**
713     * Returns the constructor or method if it is defined by {@code clazz}; null
714     * otherwise. This may return a non-public member.
715     *
716     * @param name the method name, or "<init>" to get a constructor.
717     */
718    static native Member getDeclaredConstructorOrMethod(Class clazz, String name, Class[] args);
719
720    /**
721     * Returns the declaring {@code Class} of this {@code Class}. Returns
722     * {@code null} if the class is not a member of another class or if this
723     * {@code Class} represents an array class, a primitive type or void.
724     *
725     * @return the declaring {@code Class} or {@code null}.
726     */
727    native public Class<?> getDeclaringClass();
728
729    /**
730     * Returns the enclosing {@code Class} of this {@code Class}. If there is no
731     * enclosing class the method returns {@code null}.
732     *
733     * @return the enclosing {@code Class} or {@code null}.
734     */
735    native public Class<?> getEnclosingClass();
736
737    /**
738     * Gets the enclosing {@code Constructor} of this {@code Class}, if it is an
739     * anonymous or local/automatic class; otherwise {@code null}.
740     *
741     * @return the enclosing {@code Constructor} instance or {@code null}.
742     */
743    native public Constructor<?> getEnclosingConstructor();
744
745    /**
746     * Gets the enclosing {@code Method} of this {@code Class}, if it is an
747     * anonymous or local/automatic class; otherwise {@code null}.
748     *
749     * @return the enclosing {@code Method} instance or {@code null}.
750     */
751    native public Method getEnclosingMethod();
752
753    /**
754     * Gets the {@code enum} constants associated with this {@code Class}.
755     * Returns {@code null} if this {@code Class} does not represent an {@code
756     * enum} type.
757     *
758     * @return an array with the {@code enum} constants or {@code null}.
759     */
760    @SuppressWarnings("unchecked") // we only cast after confirming that this class is an enum
761    public T[] getEnumConstants() {
762        if (!isEnum()) {
763            return null;
764        }
765        return (T[]) Enum.getSharedConstants((Class) this).clone();
766    }
767
768    /**
769     * Returns a {@code Field} object which represents the public field with the
770     * specified name. This method first searches the class C represented by
771     * this {@code Class}, then the interfaces implemented by C and finally the
772     * superclasses of C.
773     *
774     * @param name
775     *            the name of the requested field.
776     * @return the public field specified by {@code name}.
777     * @throws NoSuchFieldException
778     *             if the field can not be found.
779     * @see #getDeclaredField(String)
780     */
781    public Field getField(String name) throws NoSuchFieldException {
782        if (name == null) {
783            throw new NullPointerException("name == null");
784        }
785        Field result = getPublicFieldRecursive(name);
786        if (result == null) {
787            throw new NoSuchFieldException(name);
788        }
789        return result;
790    }
791
792    private Field getPublicFieldRecursive(String name) {
793        // search superclasses
794        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
795            Field result = Class.getDeclaredField(c, name);
796            if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) {
797                return result;
798            }
799        }
800
801        // search implemented interfaces
802        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
803            for (Class<?> ifc : c.getInterfaces()) {
804                Field result = ifc.getPublicFieldRecursive(name);
805                if (result != null && (result.getModifiers() & Modifier.PUBLIC) != 0) {
806                    return result;
807                }
808            }
809        }
810
811        return null;
812    }
813
814    /**
815     * Returns an array containing {@code Field} objects for all public fields
816     * for the class C represented by this {@code Class}. Fields may be declared
817     * in C, the interfaces it implements or in the superclasses of C. The
818     * elements in the returned array are in no particular order.
819     *
820     * <p>If there are no public fields or if this class represents an array class,
821     * a primitive type or {@code void} then an empty array is returned.
822     *
823     * @return an array with the public fields of the class represented by this
824     *         {@code Class}.
825     * @see #getDeclaredFields()
826     */
827    public Field[] getFields() {
828        List<Field> fields = new ArrayList<Field>();
829        getPublicFieldsRecursive(fields);
830
831        /*
832         * The result may include duplicates when clazz implements an interface
833         * through multiple paths. Remove those duplicates.
834         */
835        CollectionUtils.removeDuplicates(fields, Field.ORDER_BY_NAME_AND_DECLARING_CLASS);
836        return fields.toArray(new Field[fields.size()]);
837    }
838
839    /**
840     * Populates {@code result} with public fields defined by this class, its
841     * superclasses, and all implemented interfaces.
842     */
843    private void getPublicFieldsRecursive(List<Field> result) {
844        // search superclasses
845        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
846            for (Field field : Class.getDeclaredFields(c, true)) {
847                result.add(field);
848            }
849        }
850
851        // search implemented interfaces
852        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
853            for (Class<?> ifc : c.getInterfaces()) {
854                ifc.getPublicFieldsRecursive(result);
855            }
856        }
857    }
858
859    /**
860     * Gets the {@link Type}s of the interfaces that this {@code Class} directly
861     * implements. If the {@code Class} represents a primitive type or {@code
862     * void} then an empty array is returned.
863     *
864     * @return an array of {@link Type} instances directly implemented by the
865     *         class represented by this {@code class}.
866     */
867    public Type[] getGenericInterfaces() {
868        GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
869        parser.parseForClass(this, getSignatureAttribute());
870        return Types.getClonedTypeArray(parser.interfaceTypes);
871    }
872
873    /**
874     * Gets the {@code Type} that represents the superclass of this {@code
875     * class}.
876     *
877     * @return an instance of {@code Type} representing the superclass.
878     */
879    public Type getGenericSuperclass() {
880        GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
881        parser.parseForClass(this, getSignatureAttribute());
882        return Types.getType(parser.superclassType);
883    }
884
885    /**
886     * Returns an array of {@code Class} objects that match the interfaces
887     * specified in the {@code implements} declaration of the class represented
888     * by this {@code Class}. The order of the elements in the array is
889     * identical to the order in the original class declaration. If the class
890     * does not implement any interfaces, an empty array is returned.
891     *
892     * @return an array with the interfaces of the class represented by this
893     *         class.
894     */
895    public native Class<?>[] getInterfaces();
896
897    /**
898     * Returns a {@code Method} object which represents the public method with
899     * the specified name and parameter types. This method first searches the
900     * class C represented by this {@code Class}, then the superclasses of C and
901     * finally the interfaces implemented by C and finally the superclasses of C
902     * for a method with matching name.
903     *
904     * @param name
905     *            the requested method's name.
906     * @param parameterTypes
907     *            the parameter types of the requested method.
908     *            {@code (Class[]) null} is equivalent to the empty array.
909     * @return the public field specified by {@code name}.
910     * @throws NoSuchMethodException
911     *             if the method can not be found.
912     * @see #getDeclaredMethod(String, Class[])
913     */
914    public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException {
915        Member member = getConstructorOrMethod(name, true, true, parameterTypes);
916        if (member instanceof Constructor) {
917            throw new NoSuchMethodException(name);
918        }
919        return (Method) member;
920    }
921
922    /**
923     * Returns an array containing {@code Method} objects for all public methods
924     * for the class C represented by this {@code Class}. Methods may be
925     * declared in C, the interfaces it implements or in the superclasses of C.
926     * The elements in the returned array are in no particular order.
927     * <p>
928     * If there are no public methods or if this {@code Class} represents a
929     * primitive type or {@code void} then an empty array is returned.
930     * </p>
931     *
932     * @return an array with the methods of the class represented by this
933     *         {@code Class}.
934     * @see #getDeclaredMethods()
935     */
936    public Method[] getMethods() {
937        List<Method> methods = new ArrayList<Method>();
938        getPublicMethodsRecursive(methods);
939
940        /*
941         * Remove methods defined by multiple types, preferring to keep methods
942         * declared by derived types.
943         */
944        CollectionUtils.removeDuplicates(methods, Method.ORDER_BY_SIGNATURE);
945        return methods.toArray(new Method[methods.size()]);
946    }
947
948    /**
949     * Populates {@code result} with public methods defined by {@code clazz}, its
950     * superclasses, and all implemented interfaces, including overridden methods.
951     */
952    private void getPublicMethodsRecursive(List<Method> result) {
953        // search superclasses
954        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
955            for (Method method : Class.getDeclaredMethods(c, true)) {
956                result.add(method);
957            }
958        }
959
960        // search implemented interfaces
961        for (Class<?> c = this; c != null; c = c.getSuperclass()) {
962            for (Class<?> ifc : c.getInterfaces()) {
963                ifc.getPublicMethodsRecursive(result);
964            }
965        }
966    }
967
968    /**
969     * Returns an integer that represents the modifiers of the class represented
970     * by this {@code Class}. The returned value is a combination of bits
971     * defined by constants in the {@link Modifier} class.
972     *
973     * @return the modifiers of the class represented by this {@code Class}.
974     */
975    public int getModifiers() {
976        return getModifiers(this, false);
977    }
978
979    /*
980     * Return the modifiers for the given class.
981     *
982     * @param clazz the class of interest
983     * @ignoreInnerClassesAttrib determines whether we look for and use the
984     *     flags from an "inner class" attribute
985     */
986    private static native int getModifiers(Class<?> clazz, boolean ignoreInnerClassesAttrib);
987
988    /**
989     * Returns the name of the class represented by this {@code Class}. For a
990     * description of the format which is used, see the class definition of
991     * {@link Class}.
992     *
993     * @return the name of the class represented by this {@code Class}.
994     */
995    public String getName() {
996        String result = name;
997        return (result == null) ? (name = getNameNative()) : result;
998    }
999
1000    private native String getNameNative();
1001
1002    /**
1003     * Returns the simple name of the class represented by this {@code Class} as
1004     * defined in the source code. If there is no name (that is, the class is
1005     * anonymous) then an empty string is returned. If the receiver is an array
1006     * then the name of the underlying type with square braces appended (for
1007     * example {@code "Integer[]"}) is returned.
1008     *
1009     * @return the simple name of the class represented by this {@code Class}.
1010     */
1011    public String getSimpleName() {
1012        if (isArray()) {
1013            return getComponentType().getSimpleName() + "[]";
1014        }
1015
1016        String name = getName();
1017
1018        if (isAnonymousClass()) {
1019            return "";
1020        }
1021
1022        if (isMemberClass() || isLocalClass()) {
1023            return getInnerClassName();
1024        }
1025
1026        int dot = name.lastIndexOf('.');
1027        if (dot != -1) {
1028            return name.substring(dot + 1);
1029        }
1030
1031        return name;
1032    }
1033
1034    /*
1035     * Returns the simple name of a member or local class, or null otherwise.
1036     *
1037     * @return The name.
1038     */
1039    private native String getInnerClassName();
1040
1041    /**
1042     * Returns null.
1043     */
1044    public ProtectionDomain getProtectionDomain() {
1045        return null;
1046    }
1047
1048    /**
1049     * Returns the URL of the resource specified by {@code resName}. The mapping
1050     * between the resource name and the URL is managed by the class' class
1051     * loader.
1052     *
1053     * @param resName
1054     *            the name of the resource.
1055     * @return the requested resource's {@code URL} object or {@code null} if
1056     *         the resource can not be found.
1057     * @see ClassLoader
1058     */
1059    public URL getResource(String resName) {
1060        // Get absolute resource name, but without the leading slash
1061        if (resName.startsWith("/")) {
1062            resName = resName.substring(1);
1063        } else {
1064            String pkg = getName();
1065            int dot = pkg.lastIndexOf('.');
1066            if (dot != -1) {
1067                pkg = pkg.substring(0, dot).replace('.', '/');
1068            } else {
1069                pkg = "";
1070            }
1071
1072            resName = pkg + "/" + resName;
1073        }
1074
1075        // Delegate to proper class loader
1076        ClassLoader loader = getClassLoader();
1077        if (loader != null) {
1078            return loader.getResource(resName);
1079        } else {
1080            return ClassLoader.getSystemResource(resName);
1081        }
1082    }
1083
1084    /**
1085     * Returns a read-only stream for the contents of the resource specified by
1086     * {@code resName}. The mapping between the resource name and the stream is
1087     * managed by the class' class loader.
1088     *
1089     * @param resName
1090     *            the name of the resource.
1091     * @return a stream for the requested resource or {@code null} if no
1092     *         resource with the specified name can be found.
1093     * @see ClassLoader
1094     */
1095    public InputStream getResourceAsStream(String resName) {
1096        // Get absolute resource name, but without the leading slash
1097        if (resName.startsWith("/")) {
1098            resName = resName.substring(1);
1099        } else {
1100            String pkg = getName();
1101            int dot = pkg.lastIndexOf('.');
1102            if (dot != -1) {
1103                pkg = pkg.substring(0, dot).replace('.', '/');
1104            } else {
1105                pkg = "";
1106            }
1107
1108            resName = pkg + "/" + resName;
1109        }
1110
1111        // Delegate to proper class loader
1112        ClassLoader loader = getClassLoader();
1113        if (loader != null) {
1114            return loader.getResourceAsStream(resName);
1115        } else {
1116            return ClassLoader.getSystemResourceAsStream(resName);
1117        }
1118    }
1119
1120    /**
1121     * Returns null. (On Android, a {@code ClassLoader} can load classes from multiple dex files.
1122     * All classes from any given dex file will have the same signers, but different dex
1123     * files may have different signers. This does not fit well with the original
1124     * {@code ClassLoader}-based model of {@code getSigners}.)
1125     *
1126     * @return null.
1127     */
1128    public Object[] getSigners() {
1129        // See http://code.google.com/p/android/issues/detail?id=1766.
1130        return null;
1131    }
1132
1133    /**
1134     * Returns the {@code Class} object which represents the superclass of the
1135     * class represented by this {@code Class}. If this {@code Class} represents
1136     * the {@code Object} class, a primitive type, an interface or void then the
1137     * method returns {@code null}. If this {@code Class} represents an array
1138     * class then the {@code Object} class is returned.
1139     *
1140     * @return the superclass of the class represented by this {@code Class}.
1141     */
1142    public native Class<? super T> getSuperclass();
1143
1144    /**
1145     * Returns an array containing {@code TypeVariable} objects for type
1146     * variables declared by the generic class represented by this {@code
1147     * Class}. Returns an empty array if the class is not generic.
1148     *
1149     * @return an array with the type variables of the class represented by this
1150     *         class.
1151     */
1152    @SuppressWarnings("unchecked")
1153    public synchronized TypeVariable<Class<T>>[] getTypeParameters() {
1154        GenericSignatureParser parser = new GenericSignatureParser(getClassLoader());
1155        parser.parseForClass(this, getSignatureAttribute());
1156        return parser.formalTypeParameters.clone();
1157    }
1158
1159    /**
1160     * Indicates whether this {@code Class} represents an annotation class.
1161     *
1162     * @return {@code true} if this {@code Class} represents an annotation
1163     *         class; {@code false} otherwise.
1164     */
1165    public boolean isAnnotation() {
1166        final int ACC_ANNOTATION = 0x2000;  // not public in reflect.Modifiers
1167        int mod = getModifiers(this, true);
1168        return (mod & ACC_ANNOTATION) != 0;
1169    }
1170
1171    @Override public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
1172        if (annotationType == null) {
1173            throw new NullPointerException("annotationType == null");
1174        }
1175
1176        if (isDeclaredAnnotationPresent(annotationType)) {
1177            return true;
1178        }
1179
1180        if (annotationType.isDeclaredAnnotationPresent(Inherited.class)) {
1181            for (Class<?> sup = getSuperclass(); sup != null; sup = sup.getSuperclass()) {
1182                if (sup.isDeclaredAnnotationPresent(annotationType)) {
1183                    return true;
1184                }
1185            }
1186        }
1187
1188        return false;
1189    }
1190
1191    /**
1192     * Indicates whether the class represented by this {@code Class} is
1193     * anonymously declared.
1194     *
1195     * @return {@code true} if the class represented by this {@code Class} is
1196     *         anonymous; {@code false} otherwise.
1197     */
1198    native public boolean isAnonymousClass();
1199
1200    /**
1201     * Indicates whether the class represented by this {@code Class} is an array
1202     * class.
1203     *
1204     * @return {@code true} if the class represented by this {@code Class} is an
1205     *         array class; {@code false} otherwise.
1206     */
1207    public boolean isArray() {
1208        return getComponentType() != null;
1209    }
1210
1211    /**
1212     * Indicates whether the specified class type can be converted to the class
1213     * represented by this {@code Class}. Conversion may be done via an identity
1214     * conversion or a widening reference conversion (if either the receiver or
1215     * the argument represent primitive types, only the identity conversion
1216     * applies).
1217     *
1218     * @param cls
1219     *            the class to check.
1220     * @return {@code true} if {@code cls} can be converted to the class
1221     *         represented by this {@code Class}; {@code false} otherwise.
1222     * @throws NullPointerException
1223     *             if {@code cls} is {@code null}.
1224     */
1225    public native boolean isAssignableFrom(Class<?> cls);
1226
1227    /**
1228     * Indicates whether the class represented by this {@code Class} is an
1229     * {@code enum}.
1230     *
1231     * @return {@code true} if the class represented by this {@code Class} is an
1232     *         {@code enum}; {@code false} otherwise.
1233     */
1234    public boolean isEnum() {
1235        return ((getModifiers() & 0x4000) != 0) && (getSuperclass() == Enum.class);
1236    }
1237
1238    /**
1239     * Indicates whether the specified object can be cast to the class
1240     * represented by this {@code Class}. This is the runtime version of the
1241     * {@code instanceof} operator.
1242     *
1243     * @param object
1244     *            the object to check.
1245     * @return {@code true} if {@code object} can be cast to the type
1246     *         represented by this {@code Class}; {@code false} if {@code
1247     *         object} is {@code null} or cannot be cast.
1248     */
1249    public native boolean isInstance(Object object);
1250
1251    /**
1252     * Indicates whether this {@code Class} represents an interface.
1253     *
1254     * @return {@code true} if this {@code Class} represents an interface;
1255     *         {@code false} otherwise.
1256     */
1257    public native boolean isInterface();
1258
1259    /**
1260     * Indicates whether the class represented by this {@code Class} is defined
1261     * locally.
1262     *
1263     * @return {@code true} if the class represented by this {@code Class} is
1264     *         defined locally; {@code false} otherwise.
1265     */
1266    public boolean isLocalClass() {
1267        boolean enclosed = (getEnclosingMethod() != null ||
1268                         getEnclosingConstructor() != null);
1269        return enclosed && !isAnonymousClass();
1270    }
1271
1272    /**
1273     * Indicates whether the class represented by this {@code Class} is a member
1274     * class.
1275     *
1276     * @return {@code true} if the class represented by this {@code Class} is a
1277     *         member class; {@code false} otherwise.
1278     */
1279    public boolean isMemberClass() {
1280        return getDeclaringClass() != null;
1281    }
1282
1283    /**
1284     * Indicates whether this {@code Class} represents a primitive type.
1285     *
1286     * @return {@code true} if this {@code Class} represents a primitive type;
1287     *         {@code false} otherwise.
1288     */
1289    public native boolean isPrimitive();
1290
1291    /**
1292     * Indicates whether this {@code Class} represents a synthetic type.
1293     *
1294     * @return {@code true} if this {@code Class} represents a synthetic type;
1295     *         {@code false} otherwise.
1296     */
1297    public boolean isSynthetic() {
1298        final int ACC_SYNTHETIC = 0x1000;   // not public in reflect.Modifiers
1299        int mod = getModifiers(this, true);
1300        return (mod & ACC_SYNTHETIC) != 0;
1301    }
1302
1303    /**
1304     * Returns a new instance of the class represented by this {@code Class},
1305     * created by invoking the default (that is, zero-argument) constructor. If
1306     * there is no such constructor, or if the creation fails (either because of
1307     * a lack of available memory or because an exception is thrown by the
1308     * constructor), an {@code InstantiationException} is thrown. If the default
1309     * constructor exists but is not accessible from the context where this
1310     * method is invoked, an {@code IllegalAccessException} is thrown.
1311     *
1312     * @return a new instance of the class represented by this {@code Class}.
1313     * @throws IllegalAccessException
1314     *             if the default constructor is not visible.
1315     * @throws InstantiationException
1316     *             if the instance can not be created.
1317     */
1318    public T newInstance() throws InstantiationException, IllegalAccessException {
1319        return newInstanceImpl();
1320    }
1321
1322    private native T newInstanceImpl() throws IllegalAccessException, InstantiationException;
1323
1324    @Override
1325    public String toString() {
1326        if (isPrimitive()) {
1327            return getSimpleName();
1328        } else {
1329            return (isInterface() ? "interface " : "class ") + getName();
1330        }
1331    }
1332
1333    /**
1334     * Returns the {@code Package} of which the class represented by this
1335     * {@code Class} is a member. Returns {@code null} if no {@code Package}
1336     * object was created by the class loader of the class.
1337     *
1338     * @return Package the {@code Package} of which this {@code Class} is a
1339     *         member or {@code null}.
1340     */
1341    public Package getPackage() {
1342        // TODO This might be a hack, but the VM doesn't have the necessary info.
1343        ClassLoader loader = getClassLoader();
1344        if (loader != null) {
1345            String name = getName();
1346            int dot = name.lastIndexOf('.');
1347            return (dot != -1 ? loader.getPackage(name.substring(0, dot)) : null);
1348        }
1349        return null;
1350    }
1351
1352    /**
1353     * Returns the assertion status for the class represented by this {@code
1354     * Class}. Assertion is enabled / disabled based on the class loader,
1355     * package or class default at runtime.
1356     *
1357     * @return the assertion status for the class represented by this {@code
1358     *         Class}.
1359     */
1360    public native boolean desiredAssertionStatus();
1361
1362    /**
1363     * Casts this {@code Class} to represent a subclass of the specified class.
1364     * If successful, this {@code Class} is returned; otherwise a {@code
1365     * ClassCastException} is thrown.
1366     *
1367     * @param clazz
1368     *            the required type.
1369     * @return this {@code Class} cast as a subclass of the given type.
1370     * @throws ClassCastException
1371     *             if this {@code Class} cannot be cast to the specified type.
1372     */
1373    @SuppressWarnings("unchecked")
1374    public <U> Class<? extends U> asSubclass(Class<U> clazz) {
1375        if (clazz.isAssignableFrom(this)) {
1376            return (Class<? extends U>)this;
1377        }
1378        String actualClassName = this.getName();
1379        String desiredClassName = clazz.getName();
1380        throw new ClassCastException(actualClassName + " cannot be cast to " + desiredClassName);
1381    }
1382
1383    /**
1384     * Casts the specified object to the type represented by this {@code Class}.
1385     * If the object is {@code null} then the result is also {@code null}.
1386     *
1387     * @param obj
1388     *            the object to cast.
1389     * @return the object that has been cast.
1390     * @throws ClassCastException
1391     *             if the object cannot be cast to the specified type.
1392     */
1393    @SuppressWarnings("unchecked")
1394    public T cast(Object obj) {
1395        if (obj == null) {
1396            return null;
1397        } else if (this.isInstance(obj)) {
1398            return (T)obj;
1399        }
1400        String actualClassName = obj.getClass().getName();
1401        String desiredClassName = this.getName();
1402        throw new ClassCastException(actualClassName + " cannot be cast to " + desiredClassName);
1403    }
1404
1405    /**
1406     * Copies two arrays into one. Assumes that the destination array is large
1407     * enough.
1408     *
1409     * @param result the destination array
1410     * @param head the first source array
1411     * @param tail the second source array
1412     * @return the destination array, that is, result
1413     */
1414    private static <T extends Object> T[] arraycopy(T[] result, T[] head, T[] tail) {
1415        System.arraycopy(head, 0, result, 0, head.length);
1416        System.arraycopy(tail, 0, result, head.length, tail.length);
1417        return result;
1418    }
1419}
1420