001/* java.lang.reflect.Array - manipulate arrays by reflection 002 Copyright (C) 1998, 1999, 2001, 2003, 2005, 2007 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038 039package java.lang.reflect; 040 041import gnu.classpath.Configuration; 042 043/** 044 * Array holds static helper functions that allow you to create and 045 * manipulate arrays by reflection. Operations know how to perform widening 046 * conversions, but throw {@link IllegalArgumentException} if you attempt 047 * a narrowing conversion. Also, when accessing primitive arrays, this 048 * class performs object wrapping and unwrapping as necessary.<p> 049 * 050 * <B>Note:</B> This class returns and accepts types as Classes, even 051 * primitive types; there are Class types defined that represent each 052 * different primitive type. They are <code>java.lang.Boolean.TYPE, 053 * java.lang.Byte.TYPE,</code>, also available as <code>boolean.class, 054 * byte.class</code>, etc. These are not to be confused with the 055 * classes <code>java.lang.Boolean, java.lang.Byte</code>, etc., which are 056 * real classes. Note also that the shorthand <code>Object[].class</code> 057 * is a convenient way to get array Classes.<p> 058 * 059 * <B>Performance note:</B> This class performs best when it does not have 060 * to convert primitive types. The further along the chain it has to convert, 061 * the worse performance will be. You're best off using the array as whatever 062 * type it already is, and then converting the result. You will do even 063 * worse if you do this and use the generic set() function. 064 * 065 * @author John Keiser 066 * @author Eric Blake (ebb9@email.byu.edu) 067 * @author Per Bothner (bothner@cygnus.com) 068 * @see java.lang.Boolean#TYPE 069 * @see java.lang.Byte#TYPE 070 * @see java.lang.Short#TYPE 071 * @see java.lang.Character#TYPE 072 * @see java.lang.Integer#TYPE 073 * @see java.lang.Long#TYPE 074 * @see java.lang.Float#TYPE 075 * @see java.lang.Double#TYPE 076 * @since 1.1 077 * @status updated to 1.4 078 */ 079public final class Array 080{ 081 static 082 { 083 if (Configuration.INIT_LOAD_LIBRARY) 084 { 085 System.loadLibrary("javalangreflect"); 086 } 087 } 088 089 /** 090 * This class is uninstantiable. 091 */ 092 private Array() 093 { 094 } 095 096 /** 097 * Creates a new single-dimensioned array. 098 * @param componentType the type of the array to create 099 * @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}