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  * @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      * @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 }