1 /*
  2  * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package java.lang.reflect;
 27 
 28 import jdk.internal.vm.annotation.IntrinsicCandidate;
 29 
 30 /**
 31  * The {@code Array} class provides static methods to dynamically create and
 32  * access Java arrays.
 33  *
 34  * <p>{@code Array} permits widening conversions to occur during a get or set
 35  * operation, but throws an {@code IllegalArgumentException} if a narrowing
 36  * conversion would occur.
 37  *
 38  * @author Nakul Saraiya
 39  * @since 1.1
 40  */
 41 public final
 42 class Array {
 43 
 44     /**
 45      * Constructor.  Class Array is not instantiable.
 46      */
 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      *
 61      * <p>The number of dimensions of the new array must not
 62      * exceed 255.
 63      *
 64      * @param  componentType the {@code Class} object representing the
 65      *         component type of the new array
 66      * @param  length the length of the new array
 67      * @return the new array
 68      * @throws NullPointerException if the specified
 69      *         {@code componentType} parameter is null
 70      * @throws IllegalArgumentException if componentType is {@link
 71      *         Void#TYPE} or if the number of dimensions of the requested array
 72      *         instance exceed 255.
 73      * @throws NegativeArraySizeException if the specified {@code length}
 74      *         is negative
 75      */
 76     public static Object newInstance(Class<?> componentType, int length)
 77         throws NegativeArraySizeException {
 78         return newArray(componentType, length);
 79     }
 80 
 81     /**
 82      * Creates a new array
 83      * with the specified component type and dimensions.
 84      * If {@code componentType}
 85      * represents a non-array class or interface, the new array
 86      * has {@code dimensions.length} dimensions and
 87      * {@code componentType} as its component type. If
 88      * {@code componentType} represents an array class, the
 89      * number of dimensions of the new array is equal to the sum
 90      * of {@code dimensions.length} and the number of
 91      * dimensions of {@code componentType}. In this case, the
 92      * component type of the new array is the component type of
 93      * {@code componentType}.
 94      *
 95      * <p>The number of dimensions of the new array must not
 96      * exceed 255.
 97      *
 98      * @param componentType the {@code Class} object representing the component
 99      * type of the new array
100      * @param dimensions an array of {@code int} representing the dimensions of
101      * the new array
102      * @return the new array
103      * @throws    NullPointerException if the specified
104      * {@code componentType} argument is null
105      * @throws    IllegalArgumentException if the specified {@code dimensions}
106      * argument is a zero-dimensional array, if componentType is {@link
107      * Void#TYPE}, or if the number of dimensions of the requested array
108      * instance exceed 255.
109      * @throws    NegativeArraySizeException if any of the components in
110      * the specified {@code dimensions} argument is negative.
111      */
112     public static Object newInstance(Class<?> componentType, int... dimensions)
113         throws IllegalArgumentException, NegativeArraySizeException {
114         return multiNewArray(componentType, dimensions);
115     }
116 
117     /**
118      * Returns the length of the specified array object, as an {@code int}.
119      *
120      * @param array the array
121      * @return the length of the array
122      * @throws    IllegalArgumentException if the object argument is not
123      * an array
124      */
125     @IntrinsicCandidate
126     public static native int getLength(Object array)
127         throws IllegalArgumentException;
128 
129     /**
130      * Returns the value of the indexed component in the specified
131      * array object.  The value is automatically wrapped in an object
132      * if it has a primitive type.
133      *
134      * @param array the array
135      * @param index the index
136      * @return the (possibly wrapped) value of the indexed component in
137      * the specified array
138      * @throws    NullPointerException If the specified object is null
139      * @throws    IllegalArgumentException If the specified object is not
140      * an array
141      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
142      * argument is negative, or if it is greater than or equal to the
143      * length of the specified array
144      */
145     public static native Object get(Object array, int index)
146         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
147 
148     /**
149      * Returns the value of the indexed component in the specified
150      * array object, as a {@code boolean}.
151      *
152      * @param array the array
153      * @param index the index
154      * @return the value of the indexed component in the specified array
155      * @throws    NullPointerException If the specified object is null
156      * @throws    IllegalArgumentException If the specified object is not
157      * an array, or if the indexed element cannot be converted to the
158      * return type by an identity or widening conversion
159      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
160      * argument is negative, or if it is greater than or equal to the
161      * length of the specified array
162      * @see Array#get
163      */
164     public static native boolean getBoolean(Object array, int index)
165         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
166 
167     /**
168      * Returns the value of the indexed component in the specified
169      * array object, as a {@code byte}.
170      *
171      * @param array the array
172      * @param index the index
173      * @return the value of the indexed component in the specified array
174      * @throws    NullPointerException If the specified object is null
175      * @throws    IllegalArgumentException If the specified object is not
176      * an array, or if the indexed element cannot be converted to the
177      * return type by an identity or widening conversion
178      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
179      * argument is negative, or if it is greater than or equal to the
180      * length of the specified array
181      * @see Array#get
182      */
183     public static native byte getByte(Object array, int index)
184         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
185 
186     /**
187      * Returns the value of the indexed component in the specified
188      * array object, as a {@code char}.
189      *
190      * @param array the array
191      * @param index the index
192      * @return the value of the indexed component in the specified array
193      * @throws    NullPointerException If the specified object is null
194      * @throws    IllegalArgumentException If the specified object is not
195      * an array, or if the indexed element cannot be converted to the
196      * return type by an identity or widening conversion
197      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
198      * argument is negative, or if it is greater than or equal to the
199      * length of the specified array
200      * @see Array#get
201      */
202     public static native char getChar(Object array, int index)
203         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
204 
205     /**
206      * Returns the value of the indexed component in the specified
207      * array object, as a {@code short}.
208      *
209      * @param array the array
210      * @param index the index
211      * @return the value of the indexed component in the specified array
212      * @throws    NullPointerException If the specified object is null
213      * @throws    IllegalArgumentException If the specified object is not
214      * an array, or if the indexed element cannot be converted to the
215      * return type by an identity or widening conversion
216      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
217      * argument is negative, or if it is greater than or equal to the
218      * length of the specified array
219      * @see Array#get
220      */
221     public static native short getShort(Object array, int index)
222         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
223 
224     /**
225      * Returns the value of the indexed component in the specified
226      * array object, as an {@code int}.
227      *
228      * @param array the array
229      * @param index the index
230      * @return the value of the indexed component in the specified array
231      * @throws    NullPointerException If the specified object is null
232      * @throws    IllegalArgumentException If the specified object is not
233      * an array, or if the indexed element cannot be converted to the
234      * return type by an identity or widening conversion
235      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
236      * argument is negative, or if it is greater than or equal to the
237      * length of the specified array
238      * @see Array#get
239      */
240     public static native int getInt(Object array, int index)
241         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
242 
243     /**
244      * Returns the value of the indexed component in the specified
245      * array object, as a {@code long}.
246      *
247      * @param array the array
248      * @param index the index
249      * @return the value of the indexed component in the specified array
250      * @throws    NullPointerException If the specified object is null
251      * @throws    IllegalArgumentException If the specified object is not
252      * an array, or if the indexed element cannot be converted to the
253      * return type by an identity or widening conversion
254      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
255      * argument is negative, or if it is greater than or equal to the
256      * length of the specified array
257      * @see Array#get
258      */
259     public static native long getLong(Object array, int index)
260         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
261 
262     /**
263      * Returns the value of the indexed component in the specified
264      * array object, as a {@code float}.
265      *
266      * @param array the array
267      * @param index the index
268      * @return the value of the indexed component in the specified array
269      * @throws    NullPointerException If the specified object is null
270      * @throws    IllegalArgumentException If the specified object is not
271      * an array, or if the indexed element cannot be converted to the
272      * return type by an identity or widening conversion
273      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
274      * argument is negative, or if it is greater than or equal to the
275      * length of the specified array
276      * @see Array#get
277      */
278     public static native float getFloat(Object array, int index)
279         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
280 
281     /**
282      * Returns the value of the indexed component in the specified
283      * array object, as a {@code double}.
284      *
285      * @param array the array
286      * @param index the index
287      * @return the value of the indexed component in the specified array
288      * @throws    NullPointerException If the specified object is null
289      * @throws    IllegalArgumentException If the specified object is not
290      * an array, or if the indexed element cannot be converted to the
291      * return type by an identity or widening conversion
292      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
293      * argument is negative, or if it is greater than or equal to the
294      * length of the specified array
295      * @see Array#get
296      */
297     public static native double getDouble(Object array, int index)
298         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
299 
300     /**
301      * Sets the value of the indexed component of the specified array
302      * object to the specified new value.  The new value is first
303      * automatically unwrapped if the array has a primitive component
304      * type.
305      * @param array the array
306      * @param index the index into the array
307      * @param value the new value of the indexed component
308      * @throws    NullPointerException If the specified object argument
309      * is null
310      * @throws    IllegalArgumentException If the specified object argument
311      * is not an array, or if the array component type is primitive and
312      * an unwrapping conversion fails
313      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
314      * argument is negative, or if it is greater than or equal to
315      * the length of the specified array
316      */
317     public static native void set(Object array, int index, Object value)
318         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
319 
320     /**
321      * Sets the value of the indexed component of the specified array
322      * object to the specified {@code boolean} value.
323      * @param array the array
324      * @param index the index into the array
325      * @param z the new value of the indexed component
326      * @throws    NullPointerException If the specified object argument
327      * is null
328      * @throws    IllegalArgumentException If the specified object argument
329      * is not an array, or if the specified value cannot be converted
330      * to the underlying array's component type by an identity or a
331      * primitive widening conversion
332      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
333      * argument is negative, or if it is greater than or equal to
334      * the length of the specified array
335      * @see Array#set
336      */
337     public static native void setBoolean(Object array, int index, boolean z)
338         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
339 
340     /**
341      * Sets the value of the indexed component of the specified array
342      * object to the specified {@code byte} value.
343      * @param array the array
344      * @param index the index into the array
345      * @param b the new value of the indexed component
346      * @throws    NullPointerException If the specified object argument
347      * is null
348      * @throws    IllegalArgumentException If the specified object argument
349      * is not an array, or if the specified value cannot be converted
350      * to the underlying array's component type by an identity or a
351      * primitive widening conversion
352      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
353      * argument is negative, or if it is greater than or equal to
354      * the length of the specified array
355      * @see Array#set
356      */
357     public static native void setByte(Object array, int index, byte b)
358         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
359 
360     /**
361      * Sets the value of the indexed component of the specified array
362      * object to the specified {@code char} value.
363      * @param array the array
364      * @param index the index into the array
365      * @param c the new value of the indexed component
366      * @throws    NullPointerException If the specified object argument
367      * is null
368      * @throws    IllegalArgumentException If the specified object argument
369      * is not an array, or if the specified value cannot be converted
370      * to the underlying array's component type by an identity or a
371      * primitive widening conversion
372      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
373      * argument is negative, or if it is greater than or equal to
374      * the length of the specified array
375      * @see Array#set
376      */
377     public static native void setChar(Object array, int index, char c)
378         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
379 
380     /**
381      * Sets the value of the indexed component of the specified array
382      * object to the specified {@code short} value.
383      * @param array the array
384      * @param index the index into the array
385      * @param s the new value of the indexed component
386      * @throws    NullPointerException If the specified object argument
387      * is null
388      * @throws    IllegalArgumentException If the specified object argument
389      * is not an array, or if the specified value cannot be converted
390      * to the underlying array's component type by an identity or a
391      * primitive widening conversion
392      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
393      * argument is negative, or if it is greater than or equal to
394      * the length of the specified array
395      * @see Array#set
396      */
397     public static native void setShort(Object array, int index, short s)
398         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
399 
400     /**
401      * Sets the value of the indexed component of the specified array
402      * object to the specified {@code int} value.
403      * @param array the array
404      * @param index the index into the array
405      * @param i the new value of the indexed component
406      * @throws    NullPointerException If the specified object argument
407      * is null
408      * @throws    IllegalArgumentException If the specified object argument
409      * is not an array, or if the specified value cannot be converted
410      * to the underlying array's component type by an identity or a
411      * primitive widening conversion
412      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
413      * argument is negative, or if it is greater than or equal to
414      * the length of the specified array
415      * @see Array#set
416      */
417     public static native void setInt(Object array, int index, int i)
418         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
419 
420     /**
421      * Sets the value of the indexed component of the specified array
422      * object to the specified {@code long} value.
423      * @param array the array
424      * @param index the index into the array
425      * @param l the new value of the indexed component
426      * @throws    NullPointerException If the specified object argument
427      * is null
428      * @throws    IllegalArgumentException If the specified object argument
429      * is not an array, or if the specified value cannot be converted
430      * to the underlying array's component type by an identity or a
431      * primitive widening conversion
432      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
433      * argument is negative, or if it is greater than or equal to
434      * the length of the specified array
435      * @see Array#set
436      */
437     public static native void setLong(Object array, int index, long l)
438         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
439 
440     /**
441      * Sets the value of the indexed component of the specified array
442      * object to the specified {@code float} value.
443      * @param array the array
444      * @param index the index into the array
445      * @param f the new value of the indexed component
446      * @throws    NullPointerException If the specified object argument
447      * is null
448      * @throws    IllegalArgumentException If the specified object argument
449      * is not an array, or if the specified value cannot be converted
450      * to the underlying array's component type by an identity or a
451      * primitive widening conversion
452      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
453      * argument is negative, or if it is greater than or equal to
454      * the length of the specified array
455      * @see Array#set
456      */
457     public static native void setFloat(Object array, int index, float f)
458         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
459 
460     /**
461      * Sets the value of the indexed component of the specified array
462      * object to the specified {@code double} value.
463      * @param array the array
464      * @param index the index into the array
465      * @param d the new value of the indexed component
466      * @throws    NullPointerException If the specified object argument
467      * is null
468      * @throws    IllegalArgumentException If the specified object argument
469      * is not an array, or if the specified value cannot be converted
470      * to the underlying array's component type by an identity or a
471      * primitive widening conversion
472      * @throws    ArrayIndexOutOfBoundsException If the specified {@code index}
473      * argument is negative, or if it is greater than or equal to
474      * the length of the specified array
475      * @see Array#set
476      */
477     public static native void setDouble(Object array, int index, double d)
478         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
479 
480     /*
481      * Private
482      */
483 
484     @IntrinsicCandidate
485     private static native Object newArray(Class<?> componentType, int length)
486         throws NegativeArraySizeException;
487 
488     private static native Object multiNewArray(Class<?> componentType,
489         int[] dimensions)
490         throws IllegalArgumentException, NegativeArraySizeException;
491 
492 
493 }