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 java.util.Objects; 29 import jdk.internal.HotSpotIntrinsicCandidate; 30 31 /** 32 * The {@code Array} class provides static methods to dynamically create and 33 * access Java arrays. 34 * 35 * <p>{@code Array} permits widening conversions to occur during a get or set 36 * operation, but throws an {@code IllegalArgumentException} if a narrowing 37 * conversion would occur. 38 * 39 * @author Nakul Saraiya 40 * @since 1.1 41 */ 42 public final 43 class Array { 44 45 /** 46 * Constructor. Class Array is not instantiable. 47 */ 48 private Array() {} 49 50 /** 51 * Creates a new array with the specified component type and 52 * length. 53 * Invoking this method is equivalent to creating an array 54 * as follows: 55 * <blockquote> 56 * <pre> 57 * int[] x = {length}; 58 * Array.newInstance(componentType, x); 59 * </pre> 60 * </blockquote> 61 * 62 * <p>The number of dimensions of the new array must not 63 * exceed 255. 64 * 65 * @param componentType the {@code Class} object representing the 66 * component type of the new array 67 * @param length the length of the new array 68 * @return the new array 69 * @exception NullPointerException if the specified 70 * {@code componentType} parameter is null 71 * @exception IllegalArgumentException if componentType is {@link 72 * Void#TYPE} or if the number of dimensions of the requested array 73 * instance exceed 255. 74 * @exception NegativeArraySizeException if the specified {@code length} 75 * is negative 76 */ 77 public static Object newInstance(Class<?> componentType, int length) 78 throws NegativeArraySizeException { 79 return newArray(componentType, length); 80 } 81 82 /** 83 * Creates a new array 84 * with the specified component type and dimensions. 85 * If {@code componentType} 86 * represents a non-array class or interface, the new array 87 * has {@code dimensions.length} dimensions and 88 * {@code componentType} as its component type. If 89 * {@code componentType} represents an array class, the 90 * number of dimensions of the new array is equal to the sum 91 * of {@code dimensions.length} and the number of 92 * dimensions of {@code componentType}. In this case, the 93 * component type of the new array is the component type of 94 * {@code componentType}. 95 * 96 * <p>The number of dimensions of the new array must not 97 * exceed 255. 98 * 99 * @param componentType the {@code Class} object representing the component 100 * type of the new array 101 * @param dimensions an array of {@code int} representing the dimensions of 102 * the new array 103 * @return the new array 104 * @exception NullPointerException if the specified 105 * {@code componentType} argument is null 106 * @exception IllegalArgumentException if the specified {@code dimensions} 107 * argument is a zero-dimensional array, if componentType is {@link 108 * Void#TYPE}, or if the number of dimensions of the requested array 109 * instance exceed 255. 110 * @exception NegativeArraySizeException if any of the components in 111 * the specified {@code dimensions} argument is negative. 112 */ 113 public static Object newInstance(Class<?> componentType, int... dimensions) 114 throws IllegalArgumentException, NegativeArraySizeException { 115 return multiNewArray(componentType, dimensions); 116 } 117 118 /** 119 * Returns the length of the specified array object, as an {@code int}. 120 * 121 * @param array the array 122 * @return the length of the array 123 * @exception IllegalArgumentException if the object argument is not 124 * an array 125 */ 126 @HotSpotIntrinsicCandidate 127 public static native int getLength(Object array) 128 throws IllegalArgumentException; 129 130 /** 131 * Returns the value of the indexed component in the specified 132 * array object. The value is automatically wrapped in an object 133 * if it has a primitive type. 134 * 135 * @param array the array 136 * @param index the index 137 * @return the (possibly wrapped) value of the indexed component in 138 * the specified array 139 * @exception NullPointerException If the specified object is null 140 * @exception IllegalArgumentException If the specified object is not 141 * an array 142 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 143 * argument is negative, or if it is greater than or equal to the 144 * length of the specified array 145 */ 146 public static Object get(Object array, int index) 147 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 148 Class<?> componentType = array.getClass().getComponentType(); 149 if (componentType != null && !componentType.isPrimitive()) { 150 Object[] objArray = (Object[]) array.getClass().cast(array); 151 return objArray[index]; 152 } else { 153 return getReferenceOrPrimitive(array, index); 154 } 155 } 156 157 private static native Object getReferenceOrPrimitive(Object array, int index); 158 159 /** 160 * Returns the value of the indexed component in the specified 161 * array object, as a {@code boolean}. 162 * 163 * @param array the array 164 * @param index the index 165 * @return the value of the indexed component in the specified array 166 * @exception NullPointerException If the specified object is null 167 * @exception IllegalArgumentException If the specified object is not 168 * an array, or if the indexed element cannot be converted to the 169 * return type by an identity or widening conversion 170 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 171 * argument is negative, or if it is greater than or equal to the 172 * length of the specified array 173 * @see Array#get 174 */ 175 public static native boolean getBoolean(Object array, int index) 176 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 177 178 /** 179 * Returns the value of the indexed component in the specified 180 * array object, as a {@code byte}. 181 * 182 * @param array the array 183 * @param index the index 184 * @return the value of the indexed component in the specified array 185 * @exception NullPointerException If the specified object is null 186 * @exception IllegalArgumentException If the specified object is not 187 * an array, or if the indexed element cannot be converted to the 188 * return type by an identity or widening conversion 189 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 190 * argument is negative, or if it is greater than or equal to the 191 * length of the specified array 192 * @see Array#get 193 */ 194 public static native byte getByte(Object array, int index) 195 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 196 197 /** 198 * Returns the value of the indexed component in the specified 199 * array object, as a {@code char}. 200 * 201 * @param array the array 202 * @param index the index 203 * @return the value of the indexed component in the specified array 204 * @exception NullPointerException If the specified object is null 205 * @exception IllegalArgumentException If the specified object is not 206 * an array, or if the indexed element cannot be converted to the 207 * return type by an identity or widening conversion 208 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 209 * argument is negative, or if it is greater than or equal to the 210 * length of the specified array 211 * @see Array#get 212 */ 213 public static native char getChar(Object array, int index) 214 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 215 216 /** 217 * Returns the value of the indexed component in the specified 218 * array object, as a {@code short}. 219 * 220 * @param array the array 221 * @param index the index 222 * @return the value of the indexed component in the specified array 223 * @exception NullPointerException If the specified object is null 224 * @exception IllegalArgumentException If the specified object is not 225 * an array, or if the indexed element cannot be converted to the 226 * return type by an identity or widening conversion 227 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 228 * argument is negative, or if it is greater than or equal to the 229 * length of the specified array 230 * @see Array#get 231 */ 232 public static native short getShort(Object array, int index) 233 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 234 235 /** 236 * Returns the value of the indexed component in the specified 237 * array object, as an {@code int}. 238 * 239 * @param array the array 240 * @param index the index 241 * @return the value of the indexed component in the specified array 242 * @exception NullPointerException If the specified object is null 243 * @exception IllegalArgumentException If the specified object is not 244 * an array, or if the indexed element cannot be converted to the 245 * return type by an identity or widening conversion 246 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 247 * argument is negative, or if it is greater than or equal to the 248 * length of the specified array 249 * @see Array#get 250 */ 251 public static native int getInt(Object array, int index) 252 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 253 254 /** 255 * Returns the value of the indexed component in the specified 256 * array object, as a {@code long}. 257 * 258 * @param array the array 259 * @param index the index 260 * @return the value of the indexed component in the specified array 261 * @exception NullPointerException If the specified object is null 262 * @exception IllegalArgumentException If the specified object is not 263 * an array, or if the indexed element cannot be converted to the 264 * return type by an identity or widening conversion 265 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 266 * argument is negative, or if it is greater than or equal to the 267 * length of the specified array 268 * @see Array#get 269 */ 270 public static native long getLong(Object array, int index) 271 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 272 273 /** 274 * Returns the value of the indexed component in the specified 275 * array object, as a {@code float}. 276 * 277 * @param array the array 278 * @param index the index 279 * @return the value of the indexed component in the specified array 280 * @exception NullPointerException If the specified object is null 281 * @exception IllegalArgumentException If the specified object is not 282 * an array, or if the indexed element cannot be converted to the 283 * return type by an identity or widening conversion 284 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 285 * argument is negative, or if it is greater than or equal to the 286 * length of the specified array 287 * @see Array#get 288 */ 289 public static native float getFloat(Object array, int index) 290 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 291 292 /** 293 * Returns the value of the indexed component in the specified 294 * array object, as a {@code double}. 295 * 296 * @param array the array 297 * @param index the index 298 * @return the value of the indexed component in the specified array 299 * @exception NullPointerException If the specified object is null 300 * @exception IllegalArgumentException If the specified object is not 301 * an array, or if the indexed element cannot be converted to the 302 * return type by an identity or widening conversion 303 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 304 * argument is negative, or if it is greater than or equal to the 305 * length of the specified array 306 * @see Array#get 307 */ 308 public static native double getDouble(Object array, int index) 309 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 310 311 /** 312 * Sets the value of the indexed component of the specified array 313 * object to the specified new value. The new value is first 314 * automatically unwrapped if the array has a primitive component 315 * type. 316 * @param array the array 317 * @param index the index into the array 318 * @param value the new value of the indexed component 319 * @exception NullPointerException If the specified object argument 320 * is null 321 * @exception IllegalArgumentException If the specified object argument 322 * is not an array, or if the array component type is primitive and 323 * an unwrapping conversion fails 324 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 325 * argument is negative, or if it is greater than or equal to 326 * the length of the specified array 327 */ 328 public static void set(Object array, int index, Object value) 329 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 330 Class<?> componentType = array.getClass().getComponentType(); 331 if (componentType != null && !componentType.isPrimitive()) { 332 Object[] objArray = (Object[]) array.getClass().cast(array); 333 if (componentType.isValue()) { 334 objArray[index] = componentType.cast(Objects.requireNonNull(value)); 335 } else { 336 objArray[index] = componentType.cast(value); 337 } 338 } else { 339 setReferenceOrPrimitive(array, index, value); 340 } 341 } 342 343 private static native void setReferenceOrPrimitive(Object array, int index, Object value); 344 345 /** 346 * Sets the value of the indexed component of the specified array 347 * object to the specified {@code boolean} value. 348 * @param array the array 349 * @param index the index into the array 350 * @param z the new value of the indexed component 351 * @exception NullPointerException If the specified object argument 352 * is null 353 * @exception IllegalArgumentException If the specified object argument 354 * is not an array, or if the specified value cannot be converted 355 * to the underlying array's component type by an identity or a 356 * primitive widening conversion 357 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 358 * argument is negative, or if it is greater than or equal to 359 * the length of the specified array 360 * @see Array#set 361 */ 362 public static native void setBoolean(Object array, int index, boolean z) 363 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 364 365 /** 366 * Sets the value of the indexed component of the specified array 367 * object to the specified {@code byte} value. 368 * @param array the array 369 * @param index the index into the array 370 * @param b the new value of the indexed component 371 * @exception NullPointerException If the specified object argument 372 * is null 373 * @exception IllegalArgumentException If the specified object argument 374 * is not an array, or if the specified value cannot be converted 375 * to the underlying array's component type by an identity or a 376 * primitive widening conversion 377 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 378 * argument is negative, or if it is greater than or equal to 379 * the length of the specified array 380 * @see Array#set 381 */ 382 public static native void setByte(Object array, int index, byte b) 383 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 384 385 /** 386 * Sets the value of the indexed component of the specified array 387 * object to the specified {@code char} value. 388 * @param array the array 389 * @param index the index into the array 390 * @param c the new value of the indexed component 391 * @exception NullPointerException If the specified object argument 392 * is null 393 * @exception IllegalArgumentException If the specified object argument 394 * is not an array, or if the specified value cannot be converted 395 * to the underlying array's component type by an identity or a 396 * primitive widening conversion 397 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 398 * argument is negative, or if it is greater than or equal to 399 * the length of the specified array 400 * @see Array#set 401 */ 402 public static native void setChar(Object array, int index, char c) 403 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 404 405 /** 406 * Sets the value of the indexed component of the specified array 407 * object to the specified {@code short} value. 408 * @param array the array 409 * @param index the index into the array 410 * @param s the new value of the indexed component 411 * @exception NullPointerException If the specified object argument 412 * is null 413 * @exception IllegalArgumentException If the specified object argument 414 * is not an array, or if the specified value cannot be converted 415 * to the underlying array's component type by an identity or a 416 * primitive widening conversion 417 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 418 * argument is negative, or if it is greater than or equal to 419 * the length of the specified array 420 * @see Array#set 421 */ 422 public static native void setShort(Object array, int index, short s) 423 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 424 425 /** 426 * Sets the value of the indexed component of the specified array 427 * object to the specified {@code int} value. 428 * @param array the array 429 * @param index the index into the array 430 * @param i the new value of the indexed component 431 * @exception NullPointerException If the specified object argument 432 * is null 433 * @exception IllegalArgumentException If the specified object argument 434 * is not an array, or if the specified value cannot be converted 435 * to the underlying array's component type by an identity or a 436 * primitive widening conversion 437 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 438 * argument is negative, or if it is greater than or equal to 439 * the length of the specified array 440 * @see Array#set 441 */ 442 public static native void setInt(Object array, int index, int i) 443 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 444 445 /** 446 * Sets the value of the indexed component of the specified array 447 * object to the specified {@code long} value. 448 * @param array the array 449 * @param index the index into the array 450 * @param l the new value of the indexed component 451 * @exception NullPointerException If the specified object argument 452 * is null 453 * @exception IllegalArgumentException If the specified object argument 454 * is not an array, or if the specified value cannot be converted 455 * to the underlying array's component type by an identity or a 456 * primitive widening conversion 457 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 458 * argument is negative, or if it is greater than or equal to 459 * the length of the specified array 460 * @see Array#set 461 */ 462 public static native void setLong(Object array, int index, long l) 463 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 464 465 /** 466 * Sets the value of the indexed component of the specified array 467 * object to the specified {@code float} value. 468 * @param array the array 469 * @param index the index into the array 470 * @param f the new value of the indexed component 471 * @exception NullPointerException If the specified object argument 472 * is null 473 * @exception IllegalArgumentException If the specified object argument 474 * is not an array, or if the specified value cannot be converted 475 * to the underlying array's component type by an identity or a 476 * primitive widening conversion 477 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 478 * argument is negative, or if it is greater than or equal to 479 * the length of the specified array 480 * @see Array#set 481 */ 482 public static native void setFloat(Object array, int index, float f) 483 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 484 485 /** 486 * Sets the value of the indexed component of the specified array 487 * object to the specified {@code double} value. 488 * @param array the array 489 * @param index the index into the array 490 * @param d the new value of the indexed component 491 * @exception NullPointerException If the specified object argument 492 * is null 493 * @exception IllegalArgumentException If the specified object argument 494 * is not an array, or if the specified value cannot be converted 495 * to the underlying array's component type by an identity or a 496 * primitive widening conversion 497 * @exception ArrayIndexOutOfBoundsException If the specified {@code index} 498 * argument is negative, or if it is greater than or equal to 499 * the length of the specified array 500 * @see Array#set 501 */ 502 public static native void setDouble(Object array, int index, double d) 503 throws IllegalArgumentException, ArrayIndexOutOfBoundsException; 504 505 /* 506 * Private 507 */ 508 509 @HotSpotIntrinsicCandidate 510 private static native Object newArray(Class<?> componentType, int length) 511 throws NegativeArraySizeException; 512 513 private static native Object multiNewArray(Class<?> componentType, 514 int[] dimensions) 515 throws IllegalArgumentException, NegativeArraySizeException; 516 517 518 }