Frames | No Frames |
1: /* java.lang.reflect.Array - manipulate arrays by reflection 2: Copyright (C) 1998, 1999, 2001, 2003, 2005, 2007 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.lang.reflect; 40: 41: import gnu.classpath.Configuration; 42: 43: /** 44: * Array holds static helper functions that allow you to create and 45: * manipulate arrays by reflection. Operations know how to perform widening 46: * conversions, but throw {@link IllegalArgumentException} if you attempt 47: * a narrowing conversion. Also, when accessing primitive arrays, this 48: * class performs object wrapping and unwrapping as necessary.<p> 49: * 50: * <B>Note:</B> This class returns and accepts types as Classes, even 51: * primitive types; there are Class types defined that represent each 52: * different primitive type. They are <code>java.lang.Boolean.TYPE, 53: * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class, 54: * byte.class</code>, etc. These are not to be confused with the 55: * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are 56: * real classes. Note also that the shorthand <code>Object[].class</code> 57: * is a convenient way to get array Classes.<p> 58: * 59: * <B>Performance note:</B> This class performs best when it does not have 60: * to convert primitive types. The further along the chain it has to convert, 61: * the worse performance will be. You're best off using the array as whatever 62: * type it already is, and then converting the result. You will do even 63: * worse if you do this and use the generic set() function. 64: * 65: * @author John Keiser 66: * @author Eric Blake (ebb9@email.byu.edu) 67: * @author Per Bothner (bothner@cygnus.com) 68: * @see java.lang.Boolean#TYPE 69: * @see java.lang.Byte#TYPE 70: * @see java.lang.Short#TYPE 71: * @see java.lang.Character#TYPE 72: * @see java.lang.Integer#TYPE 73: * @see java.lang.Long#TYPE 74: * @see java.lang.Float#TYPE 75: * @see java.lang.Double#TYPE 76: * @since 1.1 77: * @status updated to 1.4 78: */ 79: public final class Array 80: { 81: static 82: { 83: if (Configuration.INIT_LOAD_LIBRARY) 84: { 85: System.loadLibrary("javalangreflect"); 86: } 87: } 88: 89: /** 90: * This class is uninstantiable. 91: */ 92: private Array() 93: { 94: } 95: 96: /** 97: * Creates a new single-dimensioned array. 98: * @param componentType the type of the array to create 99: * @param length the length of the array to create 100: * @return the created array, cast to an Object 101: * @throws NullPointerException if <code>componentType</code> is null 102: * @throws IllegalArgumentException if <code>componentType</code> is 103: * <code>Void.TYPE</code> 104: * @throws NegativeArraySizeException when length is less than 0 105: * @throws OutOfMemoryError if memory allocation fails 106: */ 107: public static native Object newInstance(Class<?> componentType, int length); 108: 109: /** 110: * Creates a new multi-dimensioned array. The new array has the same 111: * component type as the argument class, and the number of dimensions 112: * in the new array is the sum of the dimensions of the argument class 113: * and the length of the argument dimensions. Virtual Machine limitations 114: * forbid too many dimensions (usually 255 is the maximum); but even 115: * 50 dimensions of 2 elements in each dimension would exceed your memory 116: * long beforehand! 117: * 118: * @param componentType the type of the array to create. 119: * @param dimensions the dimensions of the array to create. Each element 120: * in <code>dimensions</code> makes another dimension of the new 121: * array. Thus, <code>Array.newInstance(java.lang.Boolean, 122: * new int[]{1,2,3})</code> is the same as 123: * <code>new java.lang.Boolean[1][2][3]</code> 124: * @return the created array, cast to an Object 125: * @throws NullPointerException if componentType or dimension is null 126: * @throws IllegalArgumentException if the the size of 127: * <code>dimensions</code> is 0 or exceeds the maximum number of 128: * array dimensions in the VM; or if componentType is Void.TYPE 129: * @throws NegativeArraySizeException when any of the dimensions is less 130: * than 0 131: * @throws OutOfMemoryError if memory allocation fails 132: */ 133: public static native Object newInstance(Class<?> elementType, int[] dimensions); 134: 135: /** 136: * Gets the array length. 137: * @param array the array 138: * @return the length of the array 139: * @throws IllegalArgumentException if <code>array</code> is not an array 140: * @throws NullPointerException if <code>array</code> is null 141: */ 142: public static native int getLength(Object array); 143: 144: /** 145: * Gets an element of an array. Primitive elements will be wrapped in 146: * the corresponding class type. 147: * 148: * @param array the array to access 149: * @param index the array index to access 150: * @return the element at <code>array[index]</code> 151: * @throws IllegalArgumentException if <code>array</code> is not an array 152: * @throws NullPointerException if <code>array</code> is null 153: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 154: * bounds 155: * @see #getBoolean(Object, int) 156: * @see #getByte(Object, int) 157: * @see #getChar(Object, int) 158: * @see #getShort(Object, int) 159: * @see #getInt(Object, int) 160: * @see #getLong(Object, int) 161: * @see #getFloat(Object, int) 162: * @see #getDouble(Object, int) 163: */ 164: public static native Object get(Object array, int index); 165: 166: /** 167: * Gets an element of a boolean array. 168: * 169: * @param array the array to access 170: * @param index the array index to access 171: * @return the boolean element at <code>array[index]</code> 172: * @throws IllegalArgumentException if <code>array</code> is not a boolean 173: * array 174: * @throws NullPointerException if <code>array</code> is null 175: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 176: * bounds 177: * @see #get(Object, int) 178: */ 179: public static native boolean getBoolean(Object array, int index); 180: 181: /** 182: * Gets an element of a byte array. 183: * 184: * @param array the array to access 185: * @param index the array index to access 186: * @return the byte element at <code>array[index]</code> 187: * @throws IllegalArgumentException if <code>array</code> is not a byte 188: * array 189: * @throws NullPointerException if <code>array</code> is null 190: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 191: * bounds 192: * @see #get(Object, int) 193: */ 194: public static native byte getByte(Object array, int index); 195: 196: /** 197: * Gets an element of a char array. 198: * 199: * @param array the array to access 200: * @param index the array index to access 201: * @return the char element at <code>array[index]</code> 202: * @throws IllegalArgumentException if <code>array</code> is not a char 203: * array 204: * @throws NullPointerException if <code>array</code> is null 205: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 206: * bounds 207: * @see #get(Object, int) 208: */ 209: public static native char getChar(Object array, int index); 210: 211: /** 212: * Gets an element of a short array. 213: * 214: * @param array the array to access 215: * @param index the array index to access 216: * @return the short element at <code>array[index]</code> 217: * @throws IllegalArgumentException if <code>array</code> is not a byte 218: * or char array 219: * @throws NullPointerException if <code>array</code> is null 220: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 221: * bounds 222: * @see #get(Object, int) 223: */ 224: public static native short getShort(Object array, int index); 225: 226: /** 227: * Gets an element of an int array. 228: * 229: * @param array the array to access 230: * @param index the array index to access 231: * @return the int element at <code>array[index]</code> 232: * @throws IllegalArgumentException if <code>array</code> is not a byte, 233: * char, short, or int array 234: * @throws NullPointerException if <code>array</code> is null 235: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 236: * bounds 237: * @see #get(Object, int) 238: */ 239: public static native int getInt(Object array, int index); 240: 241: /** 242: * Gets an element of a long array. 243: * 244: * @param array the array to access 245: * @param index the array index to access 246: * @return the long element at <code>array[index]</code> 247: * @throws IllegalArgumentException if <code>array</code> is not a byte, 248: * char, short, int, or long array 249: * @throws NullPointerException if <code>array</code> is null 250: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 251: * bounds 252: * @see #get(Object, int) 253: */ 254: public static native long getLong(Object array, int index); 255: 256: /** 257: * Gets an element of a float array. 258: * 259: * @param array the array to access 260: * @param index the array index to access 261: * @return the float element at <code>array[index]</code> 262: * @throws IllegalArgumentException if <code>array</code> is not a byte, 263: * char, short, int, long, or float array 264: * @throws NullPointerException if <code>array</code> is null 265: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 266: * bounds 267: * @see #get(Object, int) 268: */ 269: public static native float getFloat(Object array, int index); 270: 271: /** 272: * Gets an element of a double array. 273: * 274: * @param array the array to access 275: * @param index the array index to access 276: * @return the double element at <code>array[index]</code> 277: * @throws IllegalArgumentException if <code>array</code> is not a byte, 278: * char, short, int, long, float, or double array 279: * @throws NullPointerException if <code>array</code> is null 280: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 281: * bounds 282: * @see #get(Object, int) 283: */ 284: public static native double getDouble(Object array, int index); 285: 286: private static native Class getElementType(Object array, int index); 287: 288: private static native void set(Object array, int index, 289: Object value, Class elType); 290: 291: /** 292: * Sets an element of an array. If the array is primitive, then the new 293: * value is unwrapped and widened. 294: * 295: * @param array the array to set a value of 296: * @param index the array index to set the value to 297: * @param value the value to set 298: * @throws IllegalArgumentException if <code>array</code> is not an array, 299: * or the array is primitive and unwrapping value fails, or the 300: * value is not assignable to the array component type 301: * @throws NullPointerException if array is null, or if array is primitive 302: * and value is null 303: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 304: * bounds 305: * @see #setBoolean(Object, int, boolean) 306: * @see #setByte(Object, int, byte) 307: * @see #setChar(Object, int, char) 308: * @see #setShort(Object, int, short) 309: * @see #setInt(Object, int, int) 310: * @see #setLong(Object, int, long) 311: * @see #setFloat(Object, int, float) 312: * @see #setDouble(Object, int, double) 313: */ 314: public static void set(Object array, int index, Object value) 315: { 316: Class elType = getElementType(array, index); 317: if (! elType.isPrimitive()) 318: set(array, index, value, elType); 319: else if (value instanceof Byte) 320: setByte(array, index, ((Byte) value).byteValue()); 321: else if (value instanceof Short) 322: setShort(array, index, ((Short) value).shortValue()); 323: else if (value instanceof Integer) 324: setInt(array, index, ((Integer) value).intValue()); 325: else if (value instanceof Long) 326: setLong(array, index, ((Long) value).longValue()); 327: else if (value instanceof Float) 328: setFloat(array, index, ((Float) value).floatValue()); 329: else if (value instanceof Double) 330: setDouble(array, index, ((Double) value).doubleValue()); 331: else if (value instanceof Character) 332: setChar(array, index, ((Character) value).charValue()); 333: else if (value instanceof Boolean) 334: setBoolean(array, index, ((Boolean) value).booleanValue()); 335: else 336: throw new IllegalArgumentException(); 337: } 338: 339: /** 340: * Sets an element of a boolean array. 341: * 342: * @param array the array to set a value of 343: * @param index the array index to set the value to 344: * @param value the value to set 345: * @throws IllegalArgumentException if <code>array</code> is not a boolean 346: * array 347: * @throws NullPointerException if <code>array</code> is null 348: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 349: * bounds 350: * @see #set(Object, int, Object) 351: */ 352: public static native void setBoolean(Object array, int index, boolean value); 353: 354: /** 355: * Sets an element of a byte array. 356: * 357: * @param array the array to set a value of 358: * @param index the array index to set the value to 359: * @param value the value to set 360: * @throws IllegalArgumentException if <code>array</code> is not a byte, 361: * short, int, long, float, or double array 362: * @throws NullPointerException if <code>array</code> is null 363: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 364: * bounds 365: * @see #set(Object, int, Object) 366: */ 367: public static native void setByte(Object array, int index, byte value); 368: 369: /** 370: * Sets an element of a char array. 371: * 372: * @param array the array to set a value of 373: * @param index the array index to set the value to 374: * @param value the value to set 375: * @throws IllegalArgumentException if <code>array</code> is not a char, 376: * int, long, float, or double array 377: * @throws NullPointerException if <code>array</code> is null 378: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 379: * bounds 380: * @see #set(Object, int, Object) 381: */ 382: public static native void setChar(Object array, int index, char value); 383: 384: /** 385: * Sets an element of a short array. 386: * 387: * @param array the array to set a value of 388: * @param index the array index to set the value to 389: * @param value the value to set 390: * @throws IllegalArgumentException if <code>array</code> is not a short, 391: * int, long, float, or double array 392: * @throws NullPointerException if <code>array</code> is null 393: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 394: * bounds 395: * @see #set(Object, int, Object) 396: */ 397: public static native void setShort(Object array, int index, short value); 398: 399: /** 400: * Sets an element of an int array. 401: * 402: * @param array the array to set a value of 403: * @param index the array index to set the value to 404: * @param value the value to set 405: * @throws IllegalArgumentException if <code>array</code> is not an int, 406: * long, float, or double array 407: * @throws NullPointerException if <code>array</code> is null 408: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 409: * bounds 410: * @see #set(Object, int, Object) 411: */ 412: public static native void setInt(Object array, int index, int value); 413: 414: /** 415: * Sets an element of a long array. 416: * 417: * @param array the array to set a value of 418: * @param index the array index to set the value to 419: * @param value the value to set 420: * @throws IllegalArgumentException if <code>array</code> is not a long, 421: * float, or double array 422: * @throws NullPointerException if <code>array</code> is null 423: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 424: * bounds 425: * @see #set(Object, int, Object) 426: */ 427: public static native void setLong(Object array, int index, long value); 428: 429: /** 430: * Sets an element of a float array. 431: * 432: * @param array the array to set a value of 433: * @param index the array index to set the value to 434: * @param value the value to set 435: * @throws IllegalArgumentException if <code>array</code> is not a float 436: * or double array 437: * @throws NullPointerException if <code>array</code> is null 438: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 439: * bounds 440: * @see #set(Object, int, Object) 441: */ 442: public static native void setFloat(Object array, int index, float value); 443: 444: /** 445: * Sets an element of a double array. 446: * 447: * @param array the array to set a value of 448: * @param index the array index to set the value to 449: * @param value the value to set 450: * @throws IllegalArgumentException if <code>array</code> is not a double 451: * array 452: * @throws NullPointerException if <code>array</code> is null 453: * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of 454: * bounds 455: * @see #set(Object, int, Object) 456: */ 457: public static native void setDouble(Object array, int index, double value); 458: }