1/*
2 * Copyright (c) 1996, 2013, 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
26package java.lang.reflect;
27
28import jdk.internal.HotSpotIntrinsicCandidate;
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 */
41public final
42class 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     * @exception NullPointerException if the specified
69     * {@code componentType} parameter is null
70     * @exception IllegalArgumentException if componentType is {@link
71     * Void#TYPE} or if the number of dimensions of the requested array
72     * instance exceed 255.
73     * @exception 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     * @exception NullPointerException if the specified
104     * {@code componentType} argument is null
105     * @exception 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     * @exception 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     * @exception IllegalArgumentException if the object argument is not
123     * an array
124     */
125    @HotSpotIntrinsicCandidate
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     * @exception NullPointerException If the specified object is null
139     * @exception IllegalArgumentException If the specified object is not
140     * an array
141     * @exception 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     * @exception NullPointerException If the specified object is null
156     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object is null
175     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object is null
194     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object is null
213     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object is null
232     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object is null
251     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object is null
270     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object is null
289     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object argument
309     * is null
310     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object argument
327     * is null
328     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object argument
347     * is null
348     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object argument
367     * is null
368     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object argument
387     * is null
388     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object argument
407     * is null
408     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object argument
427     * is null
428     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object argument
447     * is null
448     * @exception 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     * @exception 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     * @exception NullPointerException If the specified object argument
467     * is null
468     * @exception 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     * @exception 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    @HotSpotIntrinsicCandidate
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}
494