Array.java revision 89c1feb0a69a7707b271086e749975b3f7acacf7
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17/* 18 * Copyright (C) 2008 The Android Open Source Project 19 * 20 * Licensed under the Apache License, Version 2.0 (the "License"); 21 * you may not use this file except in compliance with the License. 22 * You may obtain a copy of the License at 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 * See the License for the specific language governing permissions and 30 * limitations under the License. 31 */ 32 33package java.lang.reflect; 34 35/** 36 * This class provides static methods to create and access arrays dynamically. 37 * 38 * @since Android 1.0 39 */ 40public final class Array { 41 42 /** 43 * Prevent this class from being instantiated. 44 */ 45 private Array(){ 46 //do nothing 47 } 48 49 /** 50 * Returns the element of the array at the specified index. This reproduces 51 * the effect of {@code array[index]}. If the array component is a primitive 52 * type, the result is automatically wrapped. 53 * 54 * @param array 55 * the array 56 * @param index 57 * the index 58 * 59 * @return the requested element, possibly wrapped 60 * 61 * @throws NullPointerException 62 * if the array is null 63 * @throws IllegalArgumentException 64 * if {@code array} is not an array 65 * @throws ArrayIndexOutOfBoundsException 66 * if {@code index < 0 || index >= array.length} 67 * 68 * @since Android 1.0 69 */ 70 public static Object get(Object array, int index) 71 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 72 if (array instanceof Object[]) 73 return ((Object[]) array)[index]; 74 75 if (array instanceof boolean[]) 76 return ((boolean[]) array)[index] ? Boolean.TRUE : Boolean.FALSE; 77 78 if (array instanceof byte[]) 79 return new Byte(((byte[]) array)[index]); 80 81 if (array instanceof char[]) 82 return new Character(((char[]) array)[index]); 83 84 if (array instanceof short[]) 85 return new Short(((short[]) array)[index]); 86 87 if (array instanceof int[]) 88 return new Integer(((int[]) array)[index]); 89 90 if (array instanceof long[]) 91 return new Long(((long[]) array)[index]); 92 93 if (array instanceof float[]) 94 return new Float(((float[]) array)[index]); 95 96 if (array instanceof double[]) 97 return new Double(((double[]) array)[index]); 98 99 if (array == null) 100 throw new NullPointerException(); 101 102 throw new IllegalArgumentException("Not an array"); 103 } 104 105 /** 106 * Returns the element of the array at the specified index, converted to a 107 * {@code boolean}, if possible. This reproduces the effect of {@code 108 * array[index]} 109 * 110 * @param array 111 * the array 112 * @param index 113 * the index 114 * 115 * @return the requested element 116 * 117 * @throws NullPointerException 118 * if the {@code array} is {@code null} 119 * @throws IllegalArgumentException 120 * if {@code array} is not an array or the element at the 121 * index position can not be converted to the return type 122 * @throws ArrayIndexOutOfBoundsException 123 * if {@code index < 0 || index >= array.length} 124 * 125 * @since Android 1.0 126 */ 127 public static boolean getBoolean(Object array, int index) 128 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 129 if (array instanceof boolean[]) { 130 return ((boolean[]) array)[index]; 131 } else if (array == null) { 132 throw new NullPointerException(); 133 } else if (array.getClass().isArray()) { 134 throw new IllegalArgumentException("Wrong array type"); 135 } else { 136 throw new IllegalArgumentException("Not an array"); 137 } 138 } 139 140 /** 141 * Returns the element of the array at the specified index, converted to a 142 * {@code byte}, if possible. This reproduces the effect of {@code 143 * array[index]} 144 * 145 * @param array 146 * the array 147 * @param index 148 * the index 149 * 150 * @return the requested element 151 * 152 * @throws NullPointerException 153 * if the {@code array} is {@code null} 154 * @throws IllegalArgumentException 155 * if {@code array} is not an array or the element at the 156 * index position can not be converted to the return type 157 * @throws ArrayIndexOutOfBoundsException 158 * if {@code index < 0 || index >= array.length} 159 * 160 * @since Android 1.0 161 */ 162 public static byte getByte(Object array, int index) 163 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 164 if (array instanceof byte[]) { 165 return ((byte[]) array)[index]; 166 } else { 167 return getBoolean(array, index) ? (byte)1 : (byte)0; 168 } 169 } 170 171 /** 172 * Returns the element of the array at the specified index, converted to a 173 * {@code char}, if possible. This reproduces the effect of {@code 174 * array[index]} 175 * 176 * @param array 177 * the array 178 * @param index 179 * the index 180 * 181 * @return the requested element 182 * 183 * @throws NullPointerException 184 * if the {@code array} is {@code null} 185 * @throws IllegalArgumentException 186 * if {@code array} is not an array or the element at the 187 * index position can not be converted to the return type 188 * @throws ArrayIndexOutOfBoundsException 189 * if {@code index < 0 || index >= array.length} 190 * 191 * @since Android 1.0 192 */ 193 public static char getChar(Object array, int index) 194 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 195 if (array instanceof char[]) { 196 return ((char[]) array)[index]; 197 } else if (array == null) { 198 throw new NullPointerException(); 199 } else if (array.getClass().isArray()) { 200 throw new IllegalArgumentException("Wrong array type"); 201 } else { 202 throw new IllegalArgumentException("Not an array"); 203 } 204 } 205 206 /** 207 * Returns the element of the array at the specified index, converted to a 208 * {@code double}, if possible. This reproduces the effect of {@code 209 * array[index]} 210 * 211 * @param array 212 * the array 213 * @param index 214 * the index 215 * 216 * @return the requested element 217 * 218 * @throws NullPointerException 219 * if the {@code array} is {@code null} 220 * @throws IllegalArgumentException 221 * if {@code array} is not an array or the element at the 222 * index position can not be converted to the return type 223 * @throws ArrayIndexOutOfBoundsException 224 * if {@code index < 0 || index >= array.length} 225 * 226 * @since Android 1.0 227 */ 228 public static double getDouble(Object array, int index) 229 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 230 if (array instanceof double[]) { 231 return ((double[]) array)[index]; 232 } else { 233 return getFloat(array, index); 234 } 235 } 236 237 /** 238 * Returns the element of the array at the specified index, converted to a 239 * {@code float}, if possible. This reproduces the effect of {@code 240 * array[index]} 241 * 242 * @param array 243 * the array 244 * @param index 245 * the index 246 * 247 * @return the requested element 248 * 249 * @throws NullPointerException 250 * if the {@code array} is {@code null} 251 * @throws IllegalArgumentException 252 * if {@code array} is not an array or the element at the 253 * index position can not be converted to the return type 254 * @throws ArrayIndexOutOfBoundsException 255 * if {@code index < 0 || index >= array.length} 256 * 257 * @since Android 1.0 258 */ 259 public static float getFloat(Object array, int index) 260 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 261 if (array instanceof float[]) { 262 return ((float[]) array)[index]; 263 } else { 264 return getLong(array, index); 265 } 266 } 267 268 /** 269 * Returns the element of the array at the specified index, converted to an 270 * {@code int}, if possible. This reproduces the effect of {@code 271 * array[index]} 272 * 273 * @param array 274 * the array 275 * @param index 276 * the index 277 * 278 * @return the requested element 279 * 280 * @throws NullPointerException 281 * if the {@code array} is {@code null} 282 * @throws IllegalArgumentException 283 * if {@code array} is not an array or the element at the 284 * index position can not be converted to the return type 285 * @throws ArrayIndexOutOfBoundsException 286 * if {@code index < 0 || index >= array.length} 287 * 288 * @since Android 1.0 289 */ 290 public static int getInt(Object array, int index) 291 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 292 if (array instanceof int[]) { 293 return ((int[]) array)[index]; 294 } else { 295 return getShort(array, index); 296 } 297 } 298 299 /** 300 * Returns the length of the array. This reproduces the effect of {@code 301 * array.length} 302 * 303 * @param array 304 * the array 305 * 306 * @return the length of the array 307 * 308 * @throws NullPointerException 309 * if the {@code array} is {@code null} 310 * @throws IllegalArgumentException 311 * if {@code array} is not an array 312 * 313 * @since Android 1.0 314 */ 315 public static int getLength(Object array) { 316 if (array instanceof Object[]) 317 return ((Object[]) array).length; 318 319 if (array instanceof boolean[]) 320 return ((boolean[]) array).length; 321 322 if (array instanceof byte[]) 323 return ((byte[]) array).length; 324 325 if (array instanceof char[]) 326 return ((char[]) array).length; 327 328 if (array instanceof short[]) 329 return ((short[]) array).length; 330 331 if (array instanceof int[]) 332 return ((int[]) array).length; 333 334 if (array instanceof long[]) 335 return ((long[]) array).length; 336 337 if (array instanceof float[]) 338 return ((float[]) array).length; 339 340 if (array instanceof double[]) 341 return ((double[]) array).length; 342 343 if (array == null) 344 throw new NullPointerException(); 345 346 throw new IllegalArgumentException("Not an array"); 347 } 348 349 /** 350 * Returns the element of the array at the specified index, converted to a 351 * {@code long}, if possible. This reproduces the effect of {@code 352 * array[index]} 353 * 354 * @param array 355 * the array 356 * @param index 357 * the index 358 * 359 * @return the requested element 360 * 361 * @throws NullPointerException 362 * if the {@code array} is {@code null} 363 * @throws IllegalArgumentException 364 * if {@code array} is not an array or the element at the 365 * index position can not be converted to the return type 366 * @throws ArrayIndexOutOfBoundsException 367 * if {@code index < 0 || index >= array.length} 368 * 369 * @since Android 1.0 370 */ 371 public static long getLong(Object array, int index) 372 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 373 if (array instanceof long[]) { 374 return ((long[]) array)[index]; 375 } else { 376 return getInt(array, index); 377 } 378 } 379 380 /** 381 * Returns the element of the array at the specified index, converted to a 382 * {@code short}, if possible. This reproduces the effect of {@code 383 * array[index]} 384 * 385 * @param array 386 * the array 387 * @param index 388 * the index 389 * 390 * @return the requested element 391 * 392 * @throws NullPointerException 393 * if the {@code array} is {@code null} 394 * @throws IllegalArgumentException 395 * if {@code array} is not an array or the element at the 396 * index position can not be converted to the return type 397 * @throws ArrayIndexOutOfBoundsException 398 * if {@code index < 0 || index >= array.length} 399 * 400 * @since Android 1.0 401 */ 402 public static short getShort(Object array, int index) 403 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 404 if (array instanceof short[]) 405 return ((short[]) array)[index]; 406 407 return getByte(array, index); 408 } 409 410 /** 411 * Returns a new multidimensional array of the specified component type and 412 * dimensions. This reproduces the effect of {@code new 413 * componentType[d0][d1]...[dn]} for a dimensions array of { d0, d1, ... , 414 * dn }. 415 * 416 * @param componentType 417 * the component type of the new array 418 * @param dimensions 419 * the dimensions of the new array 420 * 421 * @return the new array 422 * 423 * @throws NullPointerException 424 * if the component type is {@code null} 425 * @throws NegativeArraySizeException 426 * if any of the dimensions are negative 427 * @throws IllegalArgumentException 428 * if the array of dimensions is of size zero, or exceeds the 429 * limit of the number of dimension for an array (currently 255) 430 * 431 * @since Android 1.0 432 */ 433 public static Object newInstance(Class<?> componentType, int[] dimensions) 434 throws NegativeArraySizeException, IllegalArgumentException { 435 if (dimensions.length <= 0 || dimensions.length > 255) 436 throw new IllegalArgumentException("Bad number of dimensions"); 437 438 if (componentType == Void.TYPE) 439 throw new IllegalArgumentException(); 440 441 if (componentType == null) 442 throw new NullPointerException(); 443 444 return createMultiArray(componentType, dimensions); 445 } 446 447 /* 448 * Create a multi-dimensional array of objects with the specified type. 449 */ 450 native private static Object createMultiArray(Class<?> componentType, 451 int[] dimensions) throws NegativeArraySizeException; 452 453 /** 454 * Returns a new array of the specified component type and length. This 455 * reproduces the effect of {@code new componentType[size]}. 456 * 457 * @param componentType 458 * the component type of the new array 459 * @param size 460 * the length of the new array 461 * 462 * @return the new array 463 * 464 * @throws NullPointerException 465 * if the component type is null 466 * @throws NegativeArraySizeException 467 * if {@code size < 0} 468 * 469 * @since Android 1.0 470 */ 471 public static Object newInstance(Class<?> componentType, int size) 472 throws NegativeArraySizeException { 473 if (!componentType.isPrimitive()) 474 return createObjectArray(componentType, size); 475 476 if (componentType == Boolean.TYPE) 477 return new boolean[size]; 478 479 if (componentType == Byte.TYPE) 480 return new byte[size]; 481 482 if (componentType == Character.TYPE) 483 return new char[size]; 484 485 if (componentType == Short.TYPE) 486 return new short[size]; 487 488 if (componentType == Integer.TYPE) 489 return new int[size]; 490 491 if (componentType == Long.TYPE) 492 return new long[size]; 493 494 if (componentType == Float.TYPE) 495 return new float[size]; 496 497 if (componentType == Double.TYPE) 498 return new double[size]; 499 500 if (componentType == Void.TYPE) 501 throw new IllegalArgumentException(); 502 503 throw new RuntimeException(); // should be impossible 504 } 505 506 /* 507 * Create a one-dimensional array of objects with the specified type. 508 */ 509 native private static Object createObjectArray(Class<?> componentType, 510 int length) throws NegativeArraySizeException; 511 512 /** 513 * Sets the element of the array at the specified index to the value. This 514 * reproduces the effect of {@code array[index] = value}. If the array 515 * component is a primitive type, the value is automatically unwrapped. 516 * 517 * @param array 518 * the array 519 * @param index 520 * the index 521 * @param value 522 * the new value 523 * 524 * @throws NullPointerException 525 * if the {@code array} is {@code null} 526 * @throws IllegalArgumentException 527 * if {@code array} is not an array or the value cannot be 528 * converted to the array type by a widening conversion 529 * @throws ArrayIndexOutOfBoundsException 530 * if {@code index < 0 || index >= array.length} 531 * 532 * @since Android 1.0 533 */ 534 public static void set(Object array, int index, Object value) 535 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 536 if (!array.getClass().isArray()) { 537 throw new IllegalArgumentException("Not an array type"); 538 } 539 540 if (array instanceof Object[]) { 541 if (value != null && 542 !array.getClass().getComponentType().isInstance(value)) { 543 // incompatible object type for this array 544 throw new IllegalArgumentException("Wrong array type"); 545 } 546 547 ((Object[]) array)[index] = value; 548 } else { 549 if (value == null) { 550 throw new IllegalArgumentException("Primitive array can't take null values."); 551 } 552 553 if (value instanceof Boolean) 554 setBoolean(array, index, ((Boolean) value).booleanValue()); 555 else if (value instanceof Byte) 556 setByte(array, index, ((Byte) value).byteValue()); 557 else if (value instanceof Character) 558 setChar(array, index, ((Character) value).charValue()); 559 else if (value instanceof Short) 560 setShort(array, index, ((Short) value).shortValue()); 561 else if (value instanceof Integer) 562 setInt(array, index, ((Integer) value).intValue()); 563 else if (value instanceof Long) 564 setLong(array, index, ((Long) value).longValue()); 565 else if (value instanceof Float) 566 setFloat(array, index, ((Float) value).floatValue()); 567 else if (value instanceof Double) 568 setDouble(array, index, ((Double) value).doubleValue()); 569 } 570 } 571 572 /** 573 * Sets the element of the array at the specified index to the {@code 574 * boolean} value. This reproduces the effect of {@code array[index] = 575 * value}. 576 * 577 * @param array 578 * the array 579 * @param index 580 * the index 581 * @param value 582 * the new value 583 * 584 * @throws NullPointerException 585 * if the {@code array} is {@code null} 586 * @throws IllegalArgumentException 587 * if the {@code array} is not an array or the value cannot be 588 * converted to the array type by a widening conversion 589 * @throws ArrayIndexOutOfBoundsException 590 * if {@code index < 0 || index >= array.length} 591 * 592 * @since Android 1.0 593 */ 594 public static void setBoolean(Object array, int index, boolean value) { 595 if (array instanceof boolean[]) { 596 ((boolean[]) array)[index] = value; 597 } else { 598 setByte(array, index, value ? (byte)1 : (byte)0); 599 } 600 } 601 602 /** 603 * Sets the element of the array at the specified index to the {@code byte} 604 * value. This reproduces the effect of {@code array[index] = value}. 605 * 606 * @param array 607 * the array 608 * @param index 609 * the index 610 * @param value 611 * the new value 612 * 613 * @throws NullPointerException 614 * if the {@code array} is {@code null} 615 * @throws IllegalArgumentException 616 * if the {@code array} is not an array or the value cannot be 617 * converted to the array type by a widening conversion 618 * @throws ArrayIndexOutOfBoundsException 619 * if {@code index < 0 || index >= array.length} 620 * 621 * @since Android 1.0 622 */ 623 public static void setByte(Object array, int index, byte value) 624 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 625 if (array instanceof byte[]) { 626 ((byte[]) array)[index] = value; 627 } else { 628 setShort(array, index, value); 629 } 630 } 631 632 /** 633 * Set the element of the array at the specified index to the {@code char} 634 * value. This reproduces the effect of {@code array[index] = value}. 635 * 636 * @param array 637 * the array 638 * @param index 639 * the index 640 * @param value 641 * the new value 642 * 643 * @throws NullPointerException 644 * if the {@code array} is {@code null} 645 * @throws IllegalArgumentException 646 * if the {@code array} is not an array or the value cannot be 647 * converted to the array type by a widening conversion 648 * @throws ArrayIndexOutOfBoundsException 649 * if {@code index < 0 || index >= array.length} 650 * 651 * @since Android 1.0 652 */ 653 public static void setChar(Object array, int index, char value) 654 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 655 if (array instanceof char[]) { 656 ((char[]) array)[index] = value; 657 } else if (array == null) { 658 throw new NullPointerException(); 659 } else if (!array.getClass().isArray()) { 660 throw new IllegalArgumentException("Not an array"); 661 } else { 662 throw new IllegalArgumentException("Wrong array type"); 663 } 664 } 665 666 /** 667 * Set the element of the array at the specified index to the {@code double} 668 * value. This reproduces the effect of {@code array[index] = value}. 669 * 670 * @param array 671 * the array 672 * @param index 673 * the index 674 * @param value 675 * the new value 676 * 677 * @throws NullPointerException 678 * if the {@code array} is {@code null} 679 * @throws IllegalArgumentException 680 * if the {@code array} is not an array or the value cannot be 681 * converted to the array type by a widening conversion 682 * @throws ArrayIndexOutOfBoundsException 683 * if {@code index < 0 || index >= array.length} 684 * 685 * @since Android 1.0 686 */ 687 public static void setDouble(Object array, int index, double value) 688 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 689 if (array instanceof double[]) { 690 ((double[]) array)[index] = value; 691 } else if (array == null) { 692 throw new NullPointerException(); 693 } else if (!array.getClass().isArray()) { 694 throw new IllegalArgumentException("Not an array"); 695 } else { 696 throw new IllegalArgumentException("Wrong array type"); 697 } 698 } 699 700 /** 701 * Set the element of the array at the specified index to the {@code float} 702 * value. This reproduces the effect of {@code array[index] = value}. 703 * 704 * @param array 705 * the array 706 * @param index 707 * the index 708 * @param value 709 * the new value 710 * 711 * @throws NullPointerException 712 * if the {@code array} is {@code null} 713 * @throws IllegalArgumentException 714 * if the {@code array} is not an array or the value cannot be 715 * converted to the array type by a widening conversion 716 * @throws ArrayIndexOutOfBoundsException 717 * if {@code index < 0 || index >= array.length} 718 * 719 * @since Android 1.0 720 */ 721 public static void setFloat(Object array, int index, float value) 722 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 723 if (array instanceof float[]) { 724 ((float[]) array)[index] = value; 725 } else { 726 setDouble(array, index, value); 727 } 728 } 729 730 /** 731 * Set the element of the array at the specified index to the {@code int} 732 * value. This reproduces the effect of {@code array[index] = value}. 733 * 734 * @param array 735 * the array 736 * @param index 737 * the index 738 * @param value 739 * the new value 740 * 741 * @throws NullPointerException 742 * if the {@code array} is {@code null} 743 * @throws IllegalArgumentException 744 * if the {@code array} is not an array or the value cannot be 745 * converted to the array type by a widening conversion 746 * @throws ArrayIndexOutOfBoundsException 747 * if {@code index < 0 || index >= array.length} 748 * 749 * @since Android 1.0 750 */ 751 public static void setInt(Object array, int index, int value) 752 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 753 if (array instanceof int[]) { 754 ((int[]) array)[index] = value; 755 } else { 756 setLong(array, index, value); 757 } 758 } 759 760 /** 761 * Set the element of the array at the specified index to the {@code long} 762 * value. This reproduces the effect of {@code array[index] = value}. 763 * 764 * @param array 765 * the array 766 * @param index 767 * the index 768 * @param value 769 * the new value 770 * 771 * @throws NullPointerException 772 * if the {@code array} is {@code null} 773 * @throws IllegalArgumentException 774 * if the {@code array} is not an array or the value cannot be 775 * converted to the array type by a widening conversion 776 * @throws ArrayIndexOutOfBoundsException 777 * if {@code index < 0 || index >= array.length} 778 * 779 * @since Android 1.0 780 */ 781 public static void setLong(Object array, int index, long value) 782 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 783 if (array instanceof long[]) { 784 ((long[]) array)[index] = value; 785 } else { 786 setFloat(array, index, value); 787 } 788 } 789 790 /** 791 * Set the element of the array at the specified index to the {@code short} 792 * value. This reproduces the effect of {@code array[index] = value}. 793 * 794 * @param array 795 * the array 796 * @param index 797 * the index 798 * @param value 799 * the new value 800 * 801 * @throws NullPointerException 802 * if the {@code array} is {@code null} 803 * @throws IllegalArgumentException 804 * if the {@code array} is not an array or the value cannot be 805 * converted to the array type by a widening conversion 806 * @throws ArrayIndexOutOfBoundsException 807 * if {@code index < 0 || index >= array.length} 808 * 809 * @since Android 1.0 810 */ 811 public static void setShort(Object array, int index, short value) 812 throws IllegalArgumentException, ArrayIndexOutOfBoundsException { 813 if (array instanceof short[]) { 814 ((short[]) array)[index] = value; 815 } else { 816 setInt(array, index, value); 817 } 818 } 819 820} 821