Home | History | Annotate | Download | only in reflect
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
      4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      5  *
      6  * This code is free software; you can redistribute it and/or modify it
      7  * under the terms of the GNU General Public License version 2 only, as
      8  * published by the Free Software Foundation.  Oracle designates this
      9  * particular file as subject to the "Classpath" exception as provided
     10  * by Oracle in the LICENSE file that accompanied this code.
     11  *
     12  * This code is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  * version 2 for more details (a copy is included in the LICENSE file that
     16  * accompanied this code).
     17  *
     18  * You should have received a copy of the GNU General Public License version
     19  * 2 along with this work; if not, write to the Free Software Foundation,
     20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     21  *
     22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     23  * or visit www.oracle.com if you need additional information or have any
     24  * questions.
     25  */
     26 
     27 package java.lang.reflect;
     28 
     29 /**
     30  * The {@code Array} class provides static methods to dynamically create and
     31  * access Java arrays.
     32  *
     33  * <p>{@code Array} permits widening conversions to occur during a get or set
     34  * operation, but throws an {@code IllegalArgumentException} if a narrowing
     35  * conversion would occur.
     36  *
     37  * @author Nakul Saraiya
     38  */
     39 public final
     40 class Array {
     41 
     42     /**
     43      * Constructor.  Class Array is not instantiable.
     44      */
     45     private Array() {}
     46 
     47     /**
     48      * Creates a new array with the specified component type and
     49      * length.
     50      * Invoking this method is equivalent to creating an array
     51      * as follows:
     52      * <blockquote>
     53      * <pre>
     54      * int[] x = {length};
     55      * Array.newInstance(componentType, x);
     56      * </pre>
     57      * </blockquote>
     58      *
     59      * @param componentType the {@code Class} object representing the
     60      * component type of the new array
     61      * @param length the length of the new array
     62      * @return the new array
     63      * @exception NullPointerException if the specified
     64      * {@code componentType} parameter is null
     65      * @exception IllegalArgumentException if componentType is {@link Void#TYPE}
     66      * @exception NegativeArraySizeException if the specified {@code length}
     67      * is negative
     68      */
     69     public static Object newInstance(Class<?> componentType, int length)
     70         throws NegativeArraySizeException {
     71         return newArray(componentType, length);
     72     }
     73 
     74     /**
     75      * Creates a new array
     76      * with the specified component type and dimensions.
     77      * If {@code componentType}
     78      * represents a non-array class or interface, the new array
     79      * has {@code dimensions.length} dimensions and
     80      * {@code componentType} as its component type. If
     81      * {@code componentType} represents an array class, the
     82      * number of dimensions of the new array is equal to the sum
     83      * of {@code dimensions.length} and the number of
     84      * dimensions of {@code componentType}. In this case, the
     85      * component type of the new array is the component type of
     86      * {@code componentType}.
     87      *
     88      * <p>The number of dimensions of the new array must not
     89      * exceed the number of array dimensions supported by the
     90      * implementation (typically 255).
     91      *
     92      * @param componentType the {@code Class} object representing the component
     93      * type of the new array
     94      * @param dimensions an array of {@code int} representing the dimensions of
     95      * the new array
     96      * @return the new array
     97      * @exception NullPointerException if the specified
     98      * {@code componentType} argument is null
     99      * @exception IllegalArgumentException if the specified {@code dimensions}
    100      * argument is a zero-dimensional array, or if the number of
    101      * requested dimensions exceeds the limit on the number of array dimensions
    102      * supported by the implementation (typically 255), or if componentType
    103      * is {@link Void#TYPE}.
    104      * @exception NegativeArraySizeException if any of the components in
    105      * the specified {@code dimensions} argument is negative.
    106      */
    107     public static Object newInstance(Class<?> componentType, int... dimensions)
    108         throws IllegalArgumentException, NegativeArraySizeException {
    109         if (dimensions.length <= 0 || dimensions.length > 255) {
    110             throw new IllegalArgumentException("Bad number of dimensions: " + dimensions.length);
    111         }
    112         if (componentType == void.class) {
    113             throw new IllegalArgumentException("Can't allocate an array of void");
    114         }
    115         if (componentType == null) {
    116             throw new NullPointerException("componentType == null");
    117         }
    118         return createMultiArray(componentType, dimensions);
    119     }
    120 
    121     /**
    122      * Returns the length of the specified array object, as an {@code int}.
    123      *
    124      * @param array the array
    125      * @return the length of the array
    126      * @exception IllegalArgumentException if the object argument is not
    127      * an array
    128      */
    129     public static int getLength(Object array) {
    130         if (array instanceof Object[]) {
    131             return ((Object[]) array).length;
    132         } else if (array instanceof boolean[]) {
    133             return ((boolean[]) array).length;
    134         } else if (array instanceof byte[]) {
    135             return ((byte[]) array).length;
    136         } else if (array instanceof char[]) {
    137             return ((char[]) array).length;
    138         } else if (array instanceof double[]) {
    139             return ((double[]) array).length;
    140         } else if (array instanceof float[]) {
    141             return ((float[]) array).length;
    142         } else if (array instanceof int[]) {
    143             return ((int[]) array).length;
    144         } else if (array instanceof long[]) {
    145             return ((long[]) array).length;
    146         } else if (array instanceof short[]) {
    147             return ((short[]) array).length;
    148         }
    149         throw badArray(array);
    150       }
    151 
    152     /**
    153      * Returns the value of the indexed component in the specified
    154      * array object.  The value is automatically wrapped in an object
    155      * if it has a primitive type.
    156      *
    157      * @param array the array
    158      * @param index the index
    159      * @return the (possibly wrapped) value of the indexed component in
    160      * the specified array
    161      * @exception NullPointerException If the specified object is null
    162      * @exception IllegalArgumentException If the specified object is not
    163      * an array
    164      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    165      * argument is negative, or if it is greater than or equal to the
    166      * length of the specified array
    167      */
    168     public static Object get(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    169         if (array instanceof Object[]) {
    170             return ((Object[]) array)[index];
    171         }
    172         if (array instanceof boolean[]) {
    173             return ((boolean[]) array)[index] ? Boolean.TRUE : Boolean.FALSE;
    174         }
    175         if (array instanceof byte[]) {
    176             return Byte.valueOf(((byte[]) array)[index]);
    177         }
    178         if (array instanceof char[]) {
    179             return Character.valueOf(((char[]) array)[index]);
    180         }
    181         if (array instanceof short[]) {
    182             return Short.valueOf(((short[]) array)[index]);
    183         }
    184         if (array instanceof int[]) {
    185             return Integer.valueOf(((int[]) array)[index]);
    186         }
    187         if (array instanceof long[]) {
    188             return Long.valueOf(((long[]) array)[index]);
    189         }
    190         if (array instanceof float[]) {
    191             return new Float(((float[]) array)[index]);
    192         }
    193         if (array instanceof double[]) {
    194             return new Double(((double[]) array)[index]);
    195         }
    196         if (array == null) {
    197             throw new NullPointerException("array == null");
    198         }
    199         throw notAnArray(array);
    200     }
    201 
    202     /**
    203      * Returns the value of the indexed component in the specified
    204      * array object, as a {@code boolean}.
    205      *
    206      * @param array the array
    207      * @param index the index
    208      * @return the value of the indexed component in the specified array
    209      * @exception NullPointerException If the specified object is null
    210      * @exception IllegalArgumentException If the specified object is not
    211      * an array, or if the indexed element cannot be converted to the
    212      * return type by an identity or widening conversion
    213      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    214      * argument is negative, or if it is greater than or equal to the
    215      * length of the specified array
    216      * @see Array#get
    217      */
    218     public static boolean getBoolean(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    219         if (array instanceof boolean[]) {
    220             return ((boolean[]) array)[index];
    221         }
    222         throw badArray(array);
    223     }
    224 
    225     /**
    226      * Returns the value of the indexed component in the specified
    227      * array object, as a {@code byte}.
    228      *
    229      * @param array the array
    230      * @param index the index
    231      * @return the value of the indexed component in the specified array
    232      * @exception NullPointerException If the specified object is null
    233      * @exception IllegalArgumentException If the specified object is not
    234      * an array, or if the indexed element cannot be converted to the
    235      * return type by an identity or widening conversion
    236      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    237      * argument is negative, or if it is greater than or equal to the
    238      * length of the specified array
    239      * @see Array#get
    240      */
    241     public static byte getByte(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    242         if (array instanceof byte[]) {
    243             return ((byte[]) array)[index];
    244         }
    245         throw badArray(array);
    246     }
    247 
    248     /**
    249      * Returns the value of the indexed component in the specified
    250      * array object, as a {@code char}.
    251      *
    252      * @param array the array
    253      * @param index the index
    254      * @return the value of the indexed component in the specified array
    255      * @exception NullPointerException If the specified object is null
    256      * @exception IllegalArgumentException If the specified object is not
    257      * an array, or if the indexed element cannot be converted to the
    258      * return type by an identity or widening conversion
    259      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    260      * argument is negative, or if it is greater than or equal to the
    261      * length of the specified array
    262      * @see Array#get
    263      */
    264     public static char getChar(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    265         if (array instanceof char[]) {
    266             return ((char[]) array)[index];
    267         }
    268         throw badArray(array);
    269     }
    270 
    271     /**
    272      * Returns the value of the indexed component in the specified
    273      * array object, as a {@code short}.
    274      *
    275      * @param array the array
    276      * @param index the index
    277      * @return the value of the indexed component in the specified array
    278      * @exception NullPointerException If the specified object is null
    279      * @exception IllegalArgumentException If the specified object is not
    280      * an array, or if the indexed element cannot be converted to the
    281      * return type by an identity or widening conversion
    282      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    283      * argument is negative, or if it is greater than or equal to the
    284      * length of the specified array
    285      * @see Array#get
    286      */
    287     public static short getShort(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    288         if (array instanceof short[]) {
    289             return ((short[]) array)[index];
    290         } else if (array instanceof byte[]) {
    291             return ((byte[]) array)[index];
    292         }
    293         throw badArray(array);
    294     }
    295 
    296     /**
    297      * Returns the value of the indexed component in the specified
    298      * array object, as an {@code int}.
    299      *
    300      * @param array the array
    301      * @param index the index
    302      * @return the value of the indexed component in the specified array
    303      * @exception NullPointerException If the specified object is null
    304      * @exception IllegalArgumentException If the specified object is not
    305      * an array, or if the indexed element cannot be converted to the
    306      * return type by an identity or widening conversion
    307      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    308      * argument is negative, or if it is greater than or equal to the
    309      * length of the specified array
    310      * @see Array#get
    311      */
    312     public static int getInt(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    313         if (array instanceof int[]) {
    314             return ((int[]) array)[index];
    315         } else if (array instanceof byte[]) {
    316             return ((byte[]) array)[index];
    317         } else if (array instanceof char[]) {
    318             return ((char[]) array)[index];
    319         } else if (array instanceof short[]) {
    320             return ((short[]) array)[index];
    321         }
    322         throw badArray(array);
    323     }
    324 
    325     /**
    326      * Returns the value of the indexed component in the specified
    327      * array object, as a {@code long}.
    328      *
    329      * @param array the array
    330      * @param index the index
    331      * @return the value of the indexed component in the specified array
    332      * @exception NullPointerException If the specified object is null
    333      * @exception IllegalArgumentException If the specified object is not
    334      * an array, or if the indexed element cannot be converted to the
    335      * return type by an identity or widening conversion
    336      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    337      * argument is negative, or if it is greater than or equal to the
    338      * length of the specified array
    339      * @see Array#get
    340      */
    341     public static long getLong(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    342         if (array instanceof long[]) {
    343             return ((long[]) array)[index];
    344         } else if (array instanceof byte[]) {
    345             return ((byte[]) array)[index];
    346         } else if (array instanceof char[]) {
    347             return ((char[]) array)[index];
    348         } else if (array instanceof int[]) {
    349             return ((int[]) array)[index];
    350         } else if (array instanceof short[]) {
    351             return ((short[]) array)[index];
    352         }
    353         throw badArray(array);
    354     }
    355 
    356     /**
    357      * Returns the value of the indexed component in the specified
    358      * array object, as a {@code float}.
    359      *
    360      * @param array the array
    361      * @param index the index
    362      * @return the value of the indexed component in the specified array
    363      * @exception NullPointerException If the specified object is null
    364      * @exception IllegalArgumentException If the specified object is not
    365      * an array, or if the indexed element cannot be converted to the
    366      * return type by an identity or widening conversion
    367      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    368      * argument is negative, or if it is greater than or equal to the
    369      * length of the specified array
    370      * @see Array#get
    371      */
    372     public static float getFloat(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    373         if (array instanceof float[]) {
    374             return ((float[]) array)[index];
    375         } else if (array instanceof byte[]) {
    376             return ((byte[]) array)[index];
    377         } else if (array instanceof char[]) {
    378             return ((char[]) array)[index];
    379         } else if (array instanceof int[]) {
    380             return ((int[]) array)[index];
    381         } else if (array instanceof long[]) {
    382             return ((long[]) array)[index];
    383         } else if (array instanceof short[]) {
    384             return ((short[]) array)[index];
    385         }
    386         throw badArray(array);
    387     }
    388 
    389     /**
    390      * Returns the value of the indexed component in the specified
    391      * array object, as a {@code double}.
    392      *
    393      * @param array the array
    394      * @param index the index
    395      * @return the value of the indexed component in the specified array
    396      * @exception NullPointerException If the specified object is null
    397      * @exception IllegalArgumentException If the specified object is not
    398      * an array, or if the indexed element cannot be converted to the
    399      * return type by an identity or widening conversion
    400      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    401      * argument is negative, or if it is greater than or equal to the
    402      * length of the specified array
    403      * @see Array#get
    404      */
    405     public static double getDouble(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    406         if (array instanceof double[]) {
    407             return ((double[]) array)[index];
    408         } else if (array instanceof byte[]) {
    409             return ((byte[]) array)[index];
    410         } else if (array instanceof char[]) {
    411             return ((char[]) array)[index];
    412         } else if (array instanceof float[]) {
    413             return ((float[]) array)[index];
    414         } else if (array instanceof int[]) {
    415             return ((int[]) array)[index];
    416         } else if (array instanceof long[]) {
    417             return ((long[]) array)[index];
    418         } else if (array instanceof short[]) {
    419             return ((short[]) array)[index];
    420         }
    421         throw badArray(array);
    422     }
    423 
    424     /**
    425      * Sets the value of the indexed component of the specified array
    426      * object to the specified new value.  The new value is first
    427      * automatically unwrapped if the array has a primitive component
    428      * type.
    429      * @param array the array
    430      * @param index the index into the array
    431      * @param value the new value of the indexed component
    432      * @exception NullPointerException If the specified object argument
    433      * is null
    434      * @exception IllegalArgumentException If the specified object argument
    435      * is not an array, or if the array component type is primitive and
    436      * an unwrapping conversion fails
    437      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    438      * argument is negative, or if it is greater than or equal to
    439      * the length of the specified array
    440      */
    441     public static void set(Object array, int index, Object value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    442         if (!array.getClass().isArray()) {
    443             throw notAnArray(array);
    444         }
    445 
    446         if (array instanceof Object[]) {
    447             if (value != null && !array.getClass().getComponentType().isInstance(value)) {
    448                 throw incompatibleType(array);
    449             }
    450             ((Object[]) array)[index] = value;
    451         } else {
    452             if (value == null) {
    453                 throw new IllegalArgumentException("Primitive array can't take null values.");
    454             }
    455             if (value instanceof Boolean) {
    456                 setBoolean(array, index, ((Boolean) value).booleanValue());
    457             } else if (value instanceof Byte) {
    458                 setByte(array, index, ((Byte) value).byteValue());
    459             } else if (value instanceof Character) {
    460                 setChar(array, index, ((Character) value).charValue());
    461             } else if (value instanceof Short) {
    462                 setShort(array, index, ((Short) value).shortValue());
    463             } else if (value instanceof Integer) {
    464                 setInt(array, index, ((Integer) value).intValue());
    465             } else if (value instanceof Long) {
    466                 setLong(array, index, ((Long) value).longValue());
    467             } else if (value instanceof Float) {
    468                 setFloat(array, index, ((Float) value).floatValue());
    469             } else if (value instanceof Double) {
    470                 setDouble(array, index, ((Double) value).doubleValue());
    471             }
    472         }
    473     }
    474 
    475     /**
    476      * Sets the value of the indexed component of the specified array
    477      * object to the specified {@code boolean} value.
    478      * @param array the array
    479      * @param index the index into the array
    480      * @param value the new value of the indexed component
    481      * @exception NullPointerException If the specified object argument
    482      * is null
    483      * @exception IllegalArgumentException If the specified object argument
    484      * is not an array, or if the specified value cannot be converted
    485      * to the underlying array's component type by an identity or a
    486      * primitive widening conversion
    487      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    488      * argument is negative, or if it is greater than or equal to
    489      * the length of the specified array
    490      * @see Array#set
    491      */
    492     // Android changed param name s/z/value
    493     public static void setBoolean(Object array, int index, boolean value) {
    494         if (array instanceof boolean[]) {
    495             ((boolean[]) array)[index] = value;
    496         } else {
    497             throw badArray(array);
    498         }
    499     }
    500 
    501     /**
    502      * Sets the value of the indexed component of the specified array
    503      * object to the specified {@code byte} value.
    504      * @param array the array
    505      * @param index the index into the array
    506      * @param value the new value of the indexed component
    507      * @exception NullPointerException If the specified object argument
    508      * is null
    509      * @exception IllegalArgumentException If the specified object argument
    510      * is not an array, or if the specified value cannot be converted
    511      * to the underlying array's component type by an identity or a
    512      * primitive widening conversion
    513      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    514      * argument is negative, or if it is greater than or equal to
    515      * the length of the specified array
    516      * @see Array#set
    517      */
    518     // Android changed param name s/b/value
    519     public static void setByte(Object array, int index, byte value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    520         if (array instanceof byte[]) {
    521             ((byte[]) array)[index] = value;
    522         } else if (array instanceof double[]) {
    523             ((double[]) array)[index] = value;
    524         } else if (array instanceof float[]) {
    525             ((float[]) array)[index] = value;
    526         } else if (array instanceof int[]) {
    527             ((int[]) array)[index] = value;
    528         } else if (array instanceof long[]) {
    529             ((long[]) array)[index] = value;
    530         } else if (array instanceof short[]) {
    531             ((short[]) array)[index] = value;
    532         } else {
    533             throw badArray(array);
    534         }
    535     }
    536 
    537     /**
    538      * Sets the value of the indexed component of the specified array
    539      * object to the specified {@code char} value.
    540      * @param array the array
    541      * @param index the index into the array
    542      * @param value the new value of the indexed component
    543      * @exception NullPointerException If the specified object argument
    544      * is null
    545      * @exception IllegalArgumentException If the specified object argument
    546      * is not an array, or if the specified value cannot be converted
    547      * to the underlying array's component type by an identity or a
    548      * primitive widening conversion
    549      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    550      * argument is negative, or if it is greater than or equal to
    551      * the length of the specified array
    552      * @see Array#set
    553      */
    554     // Android changed param name s/c/value
    555     public static void setChar(Object array, int index, char value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    556         if (array instanceof char[]) {
    557             ((char[]) array)[index] = value;
    558         } else if (array instanceof double[]) {
    559             ((double[]) array)[index] = value;
    560         } else if (array instanceof float[]) {
    561             ((float[]) array)[index] = value;
    562         } else if (array instanceof int[]) {
    563             ((int[]) array)[index] = value;
    564         } else if (array instanceof long[]) {
    565             ((long[]) array)[index] = value;
    566         } else {
    567             throw badArray(array);
    568         }
    569     }
    570 
    571     /**
    572      * Sets the value of the indexed component of the specified array
    573      * object to the specified {@code short} value.
    574      * @param array the array
    575      * @param index the index into the array
    576      * @param value the new value of the indexed component
    577      * @exception NullPointerException If the specified object argument
    578      * is null
    579      * @exception IllegalArgumentException If the specified object argument
    580      * is not an array, or if the specified value cannot be converted
    581      * to the underlying array's component type by an identity or a
    582      * primitive widening conversion
    583      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    584      * argument is negative, or if it is greater than or equal to
    585      * the length of the specified array
    586      * @see Array#set
    587      */
    588     // Android changed param name s/s/value
    589     public static void setShort(Object array, int index, short value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    590         if (array instanceof short[]) {
    591             ((short[]) array)[index] = value;
    592         } else if (array instanceof double[]) {
    593             ((double[]) array)[index] = value;
    594         } else if (array instanceof float[]) {
    595             ((float[]) array)[index] = value;
    596         } else if (array instanceof int[]) {
    597             ((int[]) array)[index] = value;
    598         } else if (array instanceof long[]) {
    599             ((long[]) array)[index] = value;
    600         } else {
    601             throw badArray(array);
    602         }
    603     }
    604 
    605     /**
    606      * Sets the value of the indexed component of the specified array
    607      * object to the specified {@code int} value.
    608      * @param array the array
    609      * @param index the index into the array
    610      * @param value the new value of the indexed component
    611      * @exception NullPointerException If the specified object argument
    612      * is null
    613      * @exception IllegalArgumentException If the specified object argument
    614      * is not an array, or if the specified value cannot be converted
    615      * to the underlying array's component type by an identity or a
    616      * primitive widening conversion
    617      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    618      * argument is negative, or if it is greater than or equal to
    619      * the length of the specified array
    620      * @see Array#set
    621      */
    622     // Android changed param name s/i/value
    623     public static void setInt(Object array, int index, int value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    624         if (array instanceof int[]) {
    625             ((int[]) array)[index] = value;
    626         } else if (array instanceof double[]) {
    627             ((double[]) array)[index] = value;
    628         } else if (array instanceof float[]) {
    629             ((float[]) array)[index] = value;
    630         } else if (array instanceof long[]) {
    631             ((long[]) array)[index] = value;
    632         } else {
    633             throw badArray(array);
    634         }
    635     }
    636 
    637     /**
    638      * Sets the value of the indexed component of the specified array
    639      * object to the specified {@code long} value.
    640      * @param array the array
    641      * @param index the index into the array
    642      * @param value the new value of the indexed component
    643      * @exception NullPointerException If the specified object argument
    644      * is null
    645      * @exception IllegalArgumentException If the specified object argument
    646      * is not an array, or if the specified value cannot be converted
    647      * to the underlying array's component type by an identity or a
    648      * primitive widening conversion
    649      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    650      * argument is negative, or if it is greater than or equal to
    651      * the length of the specified array
    652      * @see Array#set
    653      */
    654     // Android changed param name s/l/value
    655     public static void setLong(Object array, int index, long value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    656         if (array instanceof long[]) {
    657             ((long[]) array)[index] = value;
    658         } else if (array instanceof double[]) {
    659             ((double[]) array)[index] = value;
    660         } else if (array instanceof float[]) {
    661             ((float[]) array)[index] = value;
    662         } else {
    663             throw badArray(array);
    664         }
    665     }
    666 
    667     /**
    668      * Sets the value of the indexed component of the specified array
    669      * object to the specified {@code float} value.
    670      * @param array the array
    671      * @param index the index into the array
    672      * @param value the new value of the indexed component
    673      * @exception NullPointerException If the specified object argument
    674      * is null
    675      * @exception IllegalArgumentException If the specified object argument
    676      * is not an array, or if the specified value cannot be converted
    677      * to the underlying array's component type by an identity or a
    678      * primitive widening conversion
    679      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    680      * argument is negative, or if it is greater than or equal to
    681      * the length of the specified array
    682      * @see Array#set
    683      */
    684     // Android changed param name s/f/value
    685     public static void setFloat(Object array, int index, float value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    686         if (array instanceof float[]) {
    687             ((float[]) array)[index] = value;
    688         } else if (array instanceof double[]) {
    689             ((double[]) array)[index] = value;
    690         } else {
    691             throw badArray(array);
    692         }
    693     }
    694 
    695     /**
    696      * Sets the value of the indexed component of the specified array
    697      * object to the specified {@code double} value.
    698      * @param array the array
    699      * @param index the index into the array
    700      * @param value the new value of the indexed component
    701      * @exception NullPointerException If the specified object argument
    702      * is null
    703      * @exception IllegalArgumentException If the specified object argument
    704      * is not an array, or if the specified value cannot be converted
    705      * to the underlying array's component type by an identity or a
    706      * primitive widening conversion
    707      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
    708      * argument is negative, or if it is greater than or equal to
    709      * the length of the specified array
    710      * @see Array#set
    711      */
    712     // Android changed param name s/d/value
    713     public static void setDouble(Object array, int index, double value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
    714         if (array instanceof double[]) {
    715             ((double[]) array)[index] = value;
    716         } else {
    717             throw badArray(array);
    718         }
    719     }
    720 
    721     /*
    722      * Create a multi-dimensional array of objects with the specified type.
    723      */
    724     private static native Object createMultiArray(Class<?> componentType, int[] dimensions) throws NegativeArraySizeException;
    725 
    726     /**
    727      * Returns a new array of the specified component type and length.
    728      * Equivalent to {@code new componentType[size]}.
    729      *
    730      * @throws NullPointerException
    731      *             if the component type is null
    732      * @throws NegativeArraySizeException
    733      *             if {@code size < 0}
    734      */
    735     private static Object newArray(Class<?> componentType, int size) throws NegativeArraySizeException {
    736         if (!componentType.isPrimitive()) {
    737             return createObjectArray(componentType, size);
    738         } else if (componentType == char.class) {
    739             return new char[size];
    740         } else if (componentType == int.class) {
    741             return new int[size];
    742         } else if (componentType == byte.class) {
    743             return new byte[size];
    744         } else if (componentType == boolean.class) {
    745             return new boolean[size];
    746         } else if (componentType == short.class) {
    747             return new short[size];
    748         } else if (componentType == long.class) {
    749             return new long[size];
    750         } else if (componentType == float.class) {
    751             return new float[size];
    752         } else if (componentType == double.class) {
    753             return new double[size];
    754         } else if (componentType == void.class) {
    755             throw new IllegalArgumentException("Can't allocate an array of void");
    756         }
    757         throw new AssertionError();
    758     }
    759 
    760     /*
    761      * Create a one-dimensional array of objects with the specified type.
    762      */
    763     private static native Object createObjectArray(Class<?> componentType, int length) throws NegativeArraySizeException;
    764 
    765     private static IllegalArgumentException notAnArray(Object o) {
    766         throw new IllegalArgumentException("Not an array: " + o.getClass());
    767     }
    768 
    769     private static IllegalArgumentException incompatibleType(Object o) {
    770         throw new IllegalArgumentException("Array has incompatible type: " + o.getClass());
    771     }
    772 
    773     private static RuntimeException badArray(Object array) {
    774         if (array == null) {
    775             throw new NullPointerException("array == null");
    776         } else if (!array.getClass().isArray()) {
    777             throw notAnArray(array);
    778         } else {
    779             throw incompatibleType(array);
    780         }
    781     }
    782 }
    783