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