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 
  26 package java.lang.reflect;
  27 
  28 import 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  */
  40 public final
  41 class Array {
  42 
  43     /**
  44      * Constructor.  Class Array is not instantiable.
  45      */
  46     private Array() {}
  47 
  48     /**
  49      * Creates a new array with the specified component type and
  50      * length.
  51      * Invoking this method is equivalent to creating an array
  52      * as follows:
  53      * <blockquote>
  54      * <pre>
  55      * int[] x = {length};
  56      * Array.newInstance(componentType, x);
  57      * </pre>
  58      * </blockquote>
  59      *
  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      */
  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      */
 111     public static Object newInstance(Class<?> componentType, int... dimensions)
 112         throws IllegalArgumentException, NegativeArraySizeException {
 113         return multiNewArray(componentType, dimensions);
 114     }
 115 
 116     /**
 117      * Returns the length of the specified array object, as an {@code int}.
 118      *
 119      * @param array the array
 120      * @return the length of the array
 121      * @exception IllegalArgumentException if the object argument is not
 122      * an array
 123      */
 124     @HotSpotIntrinsicCandidate
 125     public static native int getLength(Object array)
 126         throws IllegalArgumentException;
 127 
 128     /**
 129      * Returns the value of the indexed component in the specified
 130      * array object.  The value is automatically wrapped in an object
 131      * if it has a primitive type.
 132      *
 133      * @param array the array
 134      * @param index the index
 135      * @return the (possibly wrapped) value of the indexed component in
 136      * the specified array
 137      * @exception NullPointerException If the specified object is null
 138      * @exception IllegalArgumentException If the specified object is not
 139      * an array
 140      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 141      * argument is negative, or if it is greater than or equal to the
 142      * length of the specified array
 143      */
 144     public static native Object get(Object array, int index)
 145         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 146 
 147     /**
 148      * Returns the value of the indexed component in the specified
 149      * array object, as a {@code boolean}.
 150      *
 151      * @param array the array
 152      * @param index the index
 153      * @return the value of the indexed component in the specified array
 154      * @exception NullPointerException If the specified object is null
 155      * @exception IllegalArgumentException If the specified object is not
 156      * an array, or if the indexed element cannot be converted to the
 157      * return type by an identity or widening conversion
 158      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 159      * argument is negative, or if it is greater than or equal to the
 160      * length of the specified array
 161      * @see Array#get
 162      */
 163     public static native boolean getBoolean(Object array, int index)
 164         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 165 
 166     /**
 167      * Returns the value of the indexed component in the specified
 168      * array object, as a {@code byte}.
 169      *
 170      * @param array the array
 171      * @param index the index
 172      * @return the value of the indexed component in the specified array
 173      * @exception NullPointerException If the specified object is null
 174      * @exception IllegalArgumentException If the specified object is not
 175      * an array, or if the indexed element cannot be converted to the
 176      * return type by an identity or widening conversion
 177      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 178      * argument is negative, or if it is greater than or equal to the
 179      * length of the specified array
 180      * @see Array#get
 181      */
 182     public static native byte getByte(Object array, int index)
 183         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 184 
 185     /**
 186      * Returns the value of the indexed component in the specified
 187      * array object, as a {@code char}.
 188      *
 189      * @param array the array
 190      * @param index the index
 191      * @return the value of the indexed component in the specified array
 192      * @exception NullPointerException If the specified object is null
 193      * @exception IllegalArgumentException If the specified object is not
 194      * an array, or if the indexed element cannot be converted to the
 195      * return type by an identity or widening conversion
 196      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 197      * argument is negative, or if it is greater than or equal to the
 198      * length of the specified array
 199      * @see Array#get
 200      */
 201     public static native char getChar(Object array, int index)
 202         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 203 
 204     /**
 205      * Returns the value of the indexed component in the specified
 206      * array object, as a {@code short}.
 207      *
 208      * @param array the array
 209      * @param index the index
 210      * @return the value of the indexed component in the specified array
 211      * @exception NullPointerException If the specified object is null
 212      * @exception IllegalArgumentException If the specified object is not
 213      * an array, or if the indexed element cannot be converted to the
 214      * return type by an identity or widening conversion
 215      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 216      * argument is negative, or if it is greater than or equal to the
 217      * length of the specified array
 218      * @see Array#get
 219      */
 220     public static native short getShort(Object array, int index)
 221         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 222 
 223     /**
 224      * Returns the value of the indexed component in the specified
 225      * array object, as an {@code int}.
 226      *
 227      * @param array the array
 228      * @param index the index
 229      * @return the value of the indexed component in the specified array
 230      * @exception NullPointerException If the specified object is null
 231      * @exception IllegalArgumentException If the specified object is not
 232      * an array, or if the indexed element cannot be converted to the
 233      * return type by an identity or widening conversion
 234      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 235      * argument is negative, or if it is greater than or equal to the
 236      * length of the specified array
 237      * @see Array#get
 238      */
 239     public static native int getInt(Object array, int index)
 240         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 241 
 242     /**
 243      * Returns the value of the indexed component in the specified
 244      * array object, as a {@code long}.
 245      *
 246      * @param array the array
 247      * @param index the index
 248      * @return the value of the indexed component in the specified array
 249      * @exception NullPointerException If the specified object is null
 250      * @exception IllegalArgumentException If the specified object is not
 251      * an array, or if the indexed element cannot be converted to the
 252      * return type by an identity or widening conversion
 253      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 254      * argument is negative, or if it is greater than or equal to the
 255      * length of the specified array
 256      * @see Array#get
 257      */
 258     public static native long getLong(Object array, int index)
 259         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 260 
 261     /**
 262      * Returns the value of the indexed component in the specified
 263      * array object, as a {@code float}.
 264      *
 265      * @param array the array
 266      * @param index the index
 267      * @return the value of the indexed component in the specified array
 268      * @exception NullPointerException If the specified object is null
 269      * @exception IllegalArgumentException If the specified object is not
 270      * an array, or if the indexed element cannot be converted to the
 271      * return type by an identity or widening conversion
 272      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 273      * argument is negative, or if it is greater than or equal to the
 274      * length of the specified array
 275      * @see Array#get
 276      */
 277     public static native float getFloat(Object array, int index)
 278         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 279 
 280     /**
 281      * Returns the value of the indexed component in the specified
 282      * array object, as a {@code double}.
 283      *
 284      * @param array the array
 285      * @param index the index
 286      * @return the value of the indexed component in the specified array
 287      * @exception NullPointerException If the specified object is null
 288      * @exception IllegalArgumentException If the specified object is not
 289      * an array, or if the indexed element cannot be converted to the
 290      * return type by an identity or widening conversion
 291      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 292      * argument is negative, or if it is greater than or equal to the
 293      * length of the specified array
 294      * @see Array#get
 295      */
 296     public static native double getDouble(Object array, int index)
 297         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 298 
 299     /**
 300      * Sets the value of the indexed component of the specified array
 301      * object to the specified new value.  The new value is first
 302      * automatically unwrapped if the array has a primitive component
 303      * type.
 304      * @param array the array
 305      * @param index the index into the array
 306      * @param value the new value of the indexed component
 307      * @exception NullPointerException If the specified object argument
 308      * is null
 309      * @exception IllegalArgumentException If the specified object argument
 310      * is not an array, or if the array component type is primitive and
 311      * an unwrapping conversion fails
 312      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 313      * argument is negative, or if it is greater than or equal to
 314      * the length of the specified array
 315      */
 316     public static native void set(Object array, int index, Object value)
 317         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 318 
 319     /**
 320      * Sets the value of the indexed component of the specified array
 321      * object to the specified {@code boolean} value.
 322      * @param array the array
 323      * @param index the index into the array
 324      * @param z the new value of the indexed component
 325      * @exception NullPointerException If the specified object argument
 326      * is null
 327      * @exception IllegalArgumentException If the specified object argument
 328      * is not an array, or if the specified value cannot be converted
 329      * to the underlying array's component type by an identity or a
 330      * primitive widening conversion
 331      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 332      * argument is negative, or if it is greater than or equal to
 333      * the length of the specified array
 334      * @see Array#set
 335      */
 336     public static native void setBoolean(Object array, int index, boolean z)
 337         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 338 
 339     /**
 340      * Sets the value of the indexed component of the specified array
 341      * object to the specified {@code byte} value.
 342      * @param array the array
 343      * @param index the index into the array
 344      * @param b the new value of the indexed component
 345      * @exception NullPointerException If the specified object argument
 346      * is null
 347      * @exception IllegalArgumentException If the specified object argument
 348      * is not an array, or if the specified value cannot be converted
 349      * to the underlying array's component type by an identity or a
 350      * primitive widening conversion
 351      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 352      * argument is negative, or if it is greater than or equal to
 353      * the length of the specified array
 354      * @see Array#set
 355      */
 356     public static native void setByte(Object array, int index, byte b)
 357         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 358 
 359     /**
 360      * Sets the value of the indexed component of the specified array
 361      * object to the specified {@code char} value.
 362      * @param array the array
 363      * @param index the index into the array
 364      * @param c the new value of the indexed component
 365      * @exception NullPointerException If the specified object argument
 366      * is null
 367      * @exception IllegalArgumentException If the specified object argument
 368      * is not an array, or if the specified value cannot be converted
 369      * to the underlying array's component type by an identity or a
 370      * primitive widening conversion
 371      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 372      * argument is negative, or if it is greater than or equal to
 373      * the length of the specified array
 374      * @see Array#set
 375      */
 376     public static native void setChar(Object array, int index, char c)
 377         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 378 
 379     /**
 380      * Sets the value of the indexed component of the specified array
 381      * object to the specified {@code short} value.
 382      * @param array the array
 383      * @param index the index into the array
 384      * @param s the new value of the indexed component
 385      * @exception NullPointerException If the specified object argument
 386      * is null
 387      * @exception IllegalArgumentException If the specified object argument
 388      * is not an array, or if the specified value cannot be converted
 389      * to the underlying array's component type by an identity or a
 390      * primitive widening conversion
 391      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 392      * argument is negative, or if it is greater than or equal to
 393      * the length of the specified array
 394      * @see Array#set
 395      */
 396     public static native void setShort(Object array, int index, short s)
 397         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 398 
 399     /**
 400      * Sets the value of the indexed component of the specified array
 401      * object to the specified {@code int} value.
 402      * @param array the array
 403      * @param index the index into the array
 404      * @param i the new value of the indexed component
 405      * @exception NullPointerException If the specified object argument
 406      * is null
 407      * @exception IllegalArgumentException If the specified object argument
 408      * is not an array, or if the specified value cannot be converted
 409      * to the underlying array's component type by an identity or a
 410      * primitive widening conversion
 411      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 412      * argument is negative, or if it is greater than or equal to
 413      * the length of the specified array
 414      * @see Array#set
 415      */
 416     public static native void setInt(Object array, int index, int i)
 417         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 418 
 419     /**
 420      * Sets the value of the indexed component of the specified array
 421      * object to the specified {@code long} value.
 422      * @param array the array
 423      * @param index the index into the array
 424      * @param l the new value of the indexed component
 425      * @exception NullPointerException If the specified object argument
 426      * is null
 427      * @exception IllegalArgumentException If the specified object argument
 428      * is not an array, or if the specified value cannot be converted
 429      * to the underlying array's component type by an identity or a
 430      * primitive widening conversion
 431      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 432      * argument is negative, or if it is greater than or equal to
 433      * the length of the specified array
 434      * @see Array#set
 435      */
 436     public static native void setLong(Object array, int index, long l)
 437         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 438 
 439     /**
 440      * Sets the value of the indexed component of the specified array
 441      * object to the specified {@code float} value.
 442      * @param array the array
 443      * @param index the index into the array
 444      * @param f the new value of the indexed component
 445      * @exception NullPointerException If the specified object argument
 446      * is null
 447      * @exception IllegalArgumentException If the specified object argument
 448      * is not an array, or if the specified value cannot be converted
 449      * to the underlying array's component type by an identity or a
 450      * primitive widening conversion
 451      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 452      * argument is negative, or if it is greater than or equal to
 453      * the length of the specified array
 454      * @see Array#set
 455      */
 456     public static native void setFloat(Object array, int index, float f)
 457         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 458 
 459     /**
 460      * Sets the value of the indexed component of the specified array
 461      * object to the specified {@code double} value.
 462      * @param array the array
 463      * @param index the index into the array
 464      * @param d the new value of the indexed component
 465      * @exception NullPointerException If the specified object argument
 466      * is null
 467      * @exception IllegalArgumentException If the specified object argument
 468      * is not an array, or if the specified value cannot be converted
 469      * to the underlying array's component type by an identity or a
 470      * primitive widening conversion
 471      * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
 472      * argument is negative, or if it is greater than or equal to
 473      * the length of the specified array
 474      * @see Array#set
 475      */
 476     public static native void setDouble(Object array, int index, double d)
 477         throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
 478 
 479     /*
 480      * Private
 481      */
 482 
 483     @HotSpotIntrinsicCandidate
 484     private static native Object newArray(Class<?> componentType, int length)
 485         throws NegativeArraySizeException;
 486 
 487     private static native Object multiNewArray(Class<?> componentType,
 488         int[] dimensions)
 489         throws IllegalArgumentException, NegativeArraySizeException;
 490 
 491 
 492 }