Dead
[official-gcc.git] / gomp-20050608-branch / libjava / classpath / java / lang / reflect / Array.java
blob35c77da369a6dedbd1aae1b2e2b6d94705c7d3cc
1 /* java.lang.reflect.Array - manipulate arrays by reflection
2 Copyright (C) 1998, 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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.
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.
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.
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.
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. */
39 package java.lang.reflect;
41 import gnu.classpath.Configuration;
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>
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>
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.
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
79 public final class Array
81 static
83 if (Configuration.INIT_LOAD_LIBRARY)
85 System.loadLibrary("javalangreflect");
89 /**
90 * This class is uninstantiable.
92 private Array()
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
107 public static Object newInstance(Class componentType, int length)
109 if (! componentType.isPrimitive())
110 return createObjectArray(componentType, length);
111 if (componentType == boolean.class)
112 return new boolean[length];
113 if (componentType == byte.class)
114 return new byte[length];
115 if (componentType == char.class)
116 return new char[length];
117 if (componentType == short.class)
118 return new short[length];
119 if (componentType == int.class)
120 return new int[length];
121 if (componentType == long.class)
122 return new long[length];
123 if (componentType == float.class)
124 return new float[length];
125 if (componentType == double.class)
126 return new double[length];
127 // assert componentType == void.class
128 throw new IllegalArgumentException();
132 * Creates a new multi-dimensioned array. The new array has the same
133 * component type as the argument class, and the number of dimensions
134 * in the new array is the sum of the dimensions of the argument class
135 * and the length of the argument dimensions. Virtual Machine limitations
136 * forbid too many dimensions (usually 255 is the maximum); but even
137 * 50 dimensions of 2 elements in each dimension would exceed your memory
138 * long beforehand!
140 * @param componentType the type of the array to create.
141 * @param dimensions the dimensions of the array to create. Each element
142 * in <code>dimensions</code> makes another dimension of the new
143 * array. Thus, <code>Array.newInstance(java.lang.Boolean,
144 * new int[]{1,2,3})</code> is the same as
145 * <code>new java.lang.Boolean[1][2][3]</code>
146 * @return the created array, cast to an Object
147 * @throws NullPointerException if componentType or dimension is null
148 * @throws IllegalArgumentException if the the size of
149 * <code>dimensions</code> is 0 or exceeds the maximum number of
150 * array dimensions in the VM; or if componentType is Void.TYPE
151 * @throws NegativeArraySizeException when any of the dimensions is less
152 * than 0
153 * @throws OutOfMemoryError if memory allocation fails
155 public static Object newInstance(Class componentType, int[] dimensions)
157 if (dimensions.length <= 0)
158 throw new IllegalArgumentException ("Empty dimensions array.");
159 return createMultiArray(componentType, dimensions,
160 dimensions.length - 1);
164 * Gets the array length.
165 * @param array the array
166 * @return the length of the array
167 * @throws IllegalArgumentException if <code>array</code> is not an array
168 * @throws NullPointerException if <code>array</code> is null
170 public static int getLength(Object array)
172 if (array instanceof Object[])
173 return ((Object[]) array).length;
174 if (array instanceof boolean[])
175 return ((boolean[]) array).length;
176 if (array instanceof byte[])
177 return ((byte[]) array). length;
178 if (array instanceof char[])
179 return ((char[]) array).length;
180 if (array instanceof short[])
181 return ((short[]) array).length;
182 if (array instanceof int[])
183 return ((int[]) array).length;
184 if (array instanceof long[])
185 return ((long[]) array).length;
186 if (array instanceof float[])
187 return ((float[]) array).length;
188 if (array instanceof double[])
189 return ((double[]) array).length;
190 if (array == null)
191 throw new NullPointerException();
192 throw new IllegalArgumentException();
196 * Gets an element of an array. Primitive elements will be wrapped in
197 * the corresponding class type.
199 * @param array the array to access
200 * @param index the array index to access
201 * @return the element at <code>array[index]</code>
202 * @throws IllegalArgumentException if <code>array</code> is not an array
203 * @throws NullPointerException if <code>array</code> is null
204 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
205 * bounds
206 * @see #getBoolean(Object, int)
207 * @see #getByte(Object, int)
208 * @see #getChar(Object, int)
209 * @see #getShort(Object, int)
210 * @see #getInt(Object, int)
211 * @see #getLong(Object, int)
212 * @see #getFloat(Object, int)
213 * @see #getDouble(Object, int)
215 public static Object get(Object array, int index)
217 if (array instanceof Object[])
218 return ((Object[]) array)[index];
219 if (array instanceof boolean[])
220 return ((boolean[]) array)[index] ? Boolean.TRUE : Boolean.FALSE;
221 if (array instanceof byte[])
222 return new Byte(((byte[]) array)[index]);
223 if (array instanceof char[])
224 return new Character(((char[]) array)[index]);
225 if (array instanceof short[])
226 return new Short(((short[]) array)[index]);
227 if (array instanceof int[])
228 return new Integer(((int[]) array)[index]);
229 if (array instanceof long[])
230 return new Long(((long[]) array)[index]);
231 if (array instanceof float[])
232 return new Float(((float[]) array)[index]);
233 if (array instanceof double[])
234 return new Double(((double[]) array)[index]);
235 if (array == null)
236 throw new NullPointerException();
237 throw new IllegalArgumentException();
241 * Gets an element of a boolean array.
243 * @param array the array to access
244 * @param index the array index to access
245 * @return the boolean element at <code>array[index]</code>
246 * @throws IllegalArgumentException if <code>array</code> is not a boolean
247 * array
248 * @throws NullPointerException if <code>array</code> is null
249 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
250 * bounds
251 * @see #get(Object, int)
253 public static boolean getBoolean(Object array, int index)
255 if (array instanceof boolean[])
256 return ((boolean[]) array)[index];
257 if (array == null)
258 throw new NullPointerException();
259 throw new IllegalArgumentException();
263 * Gets an element of a byte array.
265 * @param array the array to access
266 * @param index the array index to access
267 * @return the byte element at <code>array[index]</code>
268 * @throws IllegalArgumentException if <code>array</code> is not a byte
269 * array
270 * @throws NullPointerException if <code>array</code> is null
271 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
272 * bounds
273 * @see #get(Object, int)
275 public static byte getByte(Object array, int index)
277 if (array instanceof byte[])
278 return ((byte[]) array)[index];
279 if (array == null)
280 throw new NullPointerException();
281 throw new IllegalArgumentException();
285 * Gets an element of a char array.
287 * @param array the array to access
288 * @param index the array index to access
289 * @return the char element at <code>array[index]</code>
290 * @throws IllegalArgumentException if <code>array</code> is not a char
291 * array
292 * @throws NullPointerException if <code>array</code> is null
293 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
294 * bounds
295 * @see #get(Object, int)
297 public static char getChar(Object array, int index)
299 if (array instanceof char[])
300 return ((char[]) array)[index];
301 if (array == null)
302 throw new NullPointerException();
303 throw new IllegalArgumentException();
307 * Gets an element of a short array.
309 * @param array the array to access
310 * @param index the array index to access
311 * @return the short element at <code>array[index]</code>
312 * @throws IllegalArgumentException if <code>array</code> is not a byte
313 * or char array
314 * @throws NullPointerException if <code>array</code> is null
315 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
316 * bounds
317 * @see #get(Object, int)
319 public static short getShort(Object array, int index)
321 if (array instanceof short[])
322 return ((short[]) array)[index];
323 return getByte(array, index);
327 * Gets an element of an int array.
329 * @param array the array to access
330 * @param index the array index to access
331 * @return the int element at <code>array[index]</code>
332 * @throws IllegalArgumentException if <code>array</code> is not a byte,
333 * char, short, or int array
334 * @throws NullPointerException if <code>array</code> is null
335 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
336 * bounds
337 * @see #get(Object, int)
339 public static int getInt(Object array, int index)
341 if (array instanceof int[])
342 return ((int[]) array)[index];
343 if (array instanceof char[])
344 return ((char[]) array)[index];
345 return getShort(array, index);
349 * Gets an element of a long array.
351 * @param array the array to access
352 * @param index the array index to access
353 * @return the long element at <code>array[index]</code>
354 * @throws IllegalArgumentException if <code>array</code> is not a byte,
355 * char, short, int, or long array
356 * @throws NullPointerException if <code>array</code> is null
357 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
358 * bounds
359 * @see #get(Object, int)
361 public static long getLong(Object array, int index)
363 if (array instanceof long[])
364 return ((long[]) array)[index];
365 return getInt(array, index);
369 * Gets an element of a float array.
371 * @param array the array to access
372 * @param index the array index to access
373 * @return the float element at <code>array[index]</code>
374 * @throws IllegalArgumentException if <code>array</code> is not a byte,
375 * char, short, int, long, or float array
376 * @throws NullPointerException if <code>array</code> is null
377 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
378 * bounds
379 * @see #get(Object, int)
381 public static float getFloat(Object array, int index)
383 if (array instanceof float[])
384 return ((float[]) array)[index];
385 return getLong(array, index);
389 * Gets an element of a double array.
391 * @param array the array to access
392 * @param index the array index to access
393 * @return the double element at <code>array[index]</code>
394 * @throws IllegalArgumentException if <code>array</code> is not a byte,
395 * char, short, int, long, float, or double array
396 * @throws NullPointerException if <code>array</code> is null
397 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
398 * bounds
399 * @see #get(Object, int)
401 public static double getDouble(Object array, int index)
403 if (array instanceof double[])
404 return ((double[]) array)[index];
405 return getFloat(array, index);
409 * Sets an element of an array. If the array is primitive, then the new
410 * value is unwrapped and widened.
412 * @param array the array to set a value of
413 * @param index the array index to set the value to
414 * @param value the value to set
415 * @throws IllegalArgumentException if <code>array</code> is not an array,
416 * or the array is primitive and unwrapping value fails, or the
417 * value is not assignable to the array component type
418 * @throws NullPointerException if array is null, or if array is primitive
419 * and value is null
420 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
421 * bounds
422 * @see #setBoolean(Object, int, boolean)
423 * @see #setByte(Object, int, byte)
424 * @see #setChar(Object, int, char)
425 * @see #setShort(Object, int, short)
426 * @see #setInt(Object, int, int)
427 * @see #setLong(Object, int, long)
428 * @see #setFloat(Object, int, float)
429 * @see #setDouble(Object, int, double)
431 public static void set(Object array, int index, Object value)
433 if (array instanceof Object[])
435 // Too bad the API won't let us throw the easier ArrayStoreException!
436 if (value != null
437 && ! array.getClass().getComponentType().isInstance(value))
438 throw new IllegalArgumentException();
439 ((Object[]) array)[index] = value;
441 else if (value instanceof Byte)
442 setByte(array, index, ((Byte) value).byteValue());
443 else if (value instanceof Short)
444 setShort(array, index, ((Short) value).shortValue());
445 else if (value instanceof Integer)
446 setInt(array, index, ((Integer) value).intValue());
447 else if (value instanceof Long)
448 setLong(array, index, ((Long) value).longValue());
449 else if (value instanceof Float)
450 setFloat(array, index, ((Float) value).floatValue());
451 else if (value instanceof Double)
452 setDouble(array, index, ((Double) value).doubleValue());
453 else if (value instanceof Character)
454 setChar(array, index, ((Character) value).charValue());
455 else if (value instanceof Boolean)
456 setBoolean(array, index, ((Boolean) value).booleanValue());
457 else if (array == null)
458 throw new NullPointerException();
459 else
460 throw new IllegalArgumentException();
464 * Sets an element of a boolean array.
466 * @param array the array to set a value of
467 * @param index the array index to set the value to
468 * @param value the value to set
469 * @throws IllegalArgumentException if <code>array</code> is not a boolean
470 * array
471 * @throws NullPointerException if <code>array</code> is null
472 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
473 * bounds
474 * @see #set(Object, int, Object)
476 public static void setBoolean(Object array, int index, boolean value)
478 if (array instanceof boolean[])
479 ((boolean[]) array)[index] = value;
480 else if (array == null)
481 throw new NullPointerException();
482 else
483 throw new IllegalArgumentException();
487 * Sets an element of a byte array.
489 * @param array the array to set a value of
490 * @param index the array index to set the value to
491 * @param value the value to set
492 * @throws IllegalArgumentException if <code>array</code> is not a byte,
493 * short, int, long, float, or double array
494 * @throws NullPointerException if <code>array</code> is null
495 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
496 * bounds
497 * @see #set(Object, int, Object)
499 public static void setByte(Object array, int index, byte value)
501 if (array instanceof byte[])
502 ((byte[]) array)[index] = value;
503 else
504 setShort(array, index, value);
508 * Sets an element of a char array.
510 * @param array the array to set a value of
511 * @param index the array index to set the value to
512 * @param value the value to set
513 * @throws IllegalArgumentException if <code>array</code> is not a char,
514 * int, long, float, or double array
515 * @throws NullPointerException if <code>array</code> is null
516 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
517 * bounds
518 * @see #set(Object, int, Object)
520 public static void setChar(Object array, int index, char value)
522 if (array instanceof char[])
523 ((char[]) array)[index] = value;
524 else
525 setInt(array, index, value);
529 * Sets an element of a short array.
531 * @param array the array to set a value of
532 * @param index the array index to set the value to
533 * @param value the value to set
534 * @throws IllegalArgumentException if <code>array</code> is not a short,
535 * int, long, float, or double array
536 * @throws NullPointerException if <code>array</code> is null
537 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
538 * bounds
539 * @see #set(Object, int, Object)
541 public static void setShort(Object array, int index, short value)
543 if (array instanceof short[])
544 ((short[]) array)[index] = value;
545 else
546 setInt(array, index, value);
550 * Sets an element of an int array.
552 * @param array the array to set a value of
553 * @param index the array index to set the value to
554 * @param value the value to set
555 * @throws IllegalArgumentException if <code>array</code> is not an int,
556 * long, float, or double array
557 * @throws NullPointerException if <code>array</code> is null
558 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
559 * bounds
560 * @see #set(Object, int, Object)
562 public static void setInt(Object array, int index, int value)
564 if (array instanceof int[])
565 ((int[]) array)[index] = value;
566 else
567 setLong(array, index, value);
571 * Sets an element of a long array.
573 * @param array the array to set a value of
574 * @param index the array index to set the value to
575 * @param value the value to set
576 * @throws IllegalArgumentException if <code>array</code> is not a long,
577 * float, or double array
578 * @throws NullPointerException if <code>array</code> is null
579 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
580 * bounds
581 * @see #set(Object, int, Object)
583 public static void setLong(Object array, int index, long value)
585 if (array instanceof long[])
586 ((long[]) array)[index] = value;
587 else
588 setFloat(array, index, value);
592 * Sets an element of a float array.
594 * @param array the array to set a value of
595 * @param index the array index to set the value to
596 * @param value the value to set
597 * @throws IllegalArgumentException if <code>array</code> is not a float
598 * or double array
599 * @throws NullPointerException if <code>array</code> is null
600 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
601 * bounds
602 * @see #set(Object, int, Object)
604 public static void setFloat(Object array, int index, float value)
606 if (array instanceof float[])
607 ((float[]) array)[index] = value;
608 else
609 setDouble(array, index, value);
613 * Sets an element of a double array.
615 * @param array the array to set a value of
616 * @param index the array index to set the value to
617 * @param value the value to set
618 * @throws IllegalArgumentException if <code>array</code> is not a double
619 * array
620 * @throws NullPointerException if <code>array</code> is null
621 * @throws ArrayIndexOutOfBoundsException if <code>index</code> is out of
622 * bounds
623 * @see #set(Object, int, Object)
625 public static void setDouble(Object array, int index, double value)
627 if (array instanceof double[])
628 ((double[]) array)[index] = value;
629 else if (array == null)
630 throw new NullPointerException();
631 else
632 throw new IllegalArgumentException();
636 * Dynamically and recursively create a multi-dimensioned array of objects.
638 * @param type guaranteed to be a valid object type
639 * @param dimensions the dimensions of the array
640 * @param index index of the current dimension to build
641 * @return the new multi-dimensioned array
642 * @throws NegativeArraySizeException if any entry of dimensions is negative
643 * @throws OutOfMemoryError if memory allocation fails
645 // This would be faster if implemented natively, using the multianewarray
646 // bytecode instead of this recursive call
647 private static Object createMultiArray(Class type, int[] dimensions,
648 int index)
650 if (index == 0)
651 return newInstance(type, dimensions[0]);
653 Object toAdd = createMultiArray(type, dimensions, index - 1);
654 Class thisType = toAdd.getClass();
655 Object[] retval
656 = (Object[]) createObjectArray(thisType, dimensions[index]);
657 if (dimensions[index] > 0)
658 retval[0] = toAdd;
659 int i = dimensions[index];
660 while (--i > 0)
661 retval[i] = createMultiArray(type, dimensions, index - 1);
662 return retval;
666 * Dynamically create an array of objects.
668 * @param type guaranteed to be a valid object type
669 * @param dim the length of the array
670 * @return the new array
671 * @throws NegativeArraySizeException if dim is negative
672 * @throws OutOfMemoryError if memory allocation fails
674 private static native Object createObjectArray(Class type, int dim);