In order to support fields of the same name in subclasses we are now prefixing them with name of the class that defines them. To provide convenient way to access them from generated bytecode and also directly from JavaScript, there is a getter/setter function for each field. It starts with _ followed by the field name. If called with a parameter, it sets the field, with a parameter it just returns it.
2 * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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.
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
26 package java.lang.reflect;
28 import org.apidesign.bck2brwsr.core.JavaScriptBody;
29 import org.apidesign.bck2brwsr.core.JavaScriptPrototype;
32 * The {@code Array} class provides static methods to dynamically create and
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.
39 * @author Nakul Saraiya
41 @JavaScriptPrototype(prototype = "new Array", container = "Array.prototype")
46 * Constructor. Class Array is not instantiable.
51 * Creates a new array with the specified component type and
53 * Invoking this method is equivalent to creating an array
58 * Array.newInstance(componentType, x);
62 * @param componentType the {@code Class} object representing the
63 * component type of the new array
64 * @param length the length of the new array
65 * @return the new array
66 * @exception NullPointerException if the specified
67 * {@code componentType} parameter is null
68 * @exception IllegalArgumentException if componentType is {@link Void#TYPE}
69 * @exception NegativeArraySizeException if the specified {@code length}
72 public static Object newInstance(Class<?> componentType, int length)
73 throws NegativeArraySizeException {
75 throw new NegativeArraySizeException();
77 String sig = findSignature(componentType);
78 return newArray(componentType.isPrimitive(), sig, length);
81 private static String findSignature(Class<?> type) {
82 if (type == Integer.TYPE) {
85 if (type == Long.TYPE) {
88 if (type == Double.TYPE) {
91 if (type == Float.TYPE) {
94 if (type == Byte.TYPE) {
97 if (type == Boolean.TYPE) {
100 if (type == Short.TYPE) {
103 if (type == Character.TYPE) {
106 if (type.getName().equals("void")) {
107 throw new IllegalStateException("Can't create array for " + type);
109 return "[L" + type.getName() + ";";
112 * Creates a new array
113 * with the specified component type and dimensions.
114 * If {@code componentType}
115 * represents a non-array class or interface, the new array
116 * has {@code dimensions.length} dimensions and
117 * {@code componentType} as its component type. If
118 * {@code componentType} represents an array class, the
119 * number of dimensions of the new array is equal to the sum
120 * of {@code dimensions.length} and the number of
121 * dimensions of {@code componentType}. In this case, the
122 * component type of the new array is the component type of
123 * {@code componentType}.
125 * <p>The number of dimensions of the new array must not
126 * exceed the number of array dimensions supported by the
127 * implementation (typically 255).
129 * @param componentType the {@code Class} object representing the component
130 * type of the new array
131 * @param dimensions an array of {@code int} representing the dimensions of
133 * @return the new array
134 * @exception NullPointerException if the specified
135 * {@code componentType} argument is null
136 * @exception IllegalArgumentException if the specified {@code dimensions}
137 * argument is a zero-dimensional array, or if the number of
138 * requested dimensions exceeds the limit on the number of array dimensions
139 * supported by the implementation (typically 255), or if componentType
140 * is {@link Void#TYPE}.
141 * @exception NegativeArraySizeException if any of the components in
142 * the specified {@code dimensions} argument is negative.
144 public static Object newInstance(Class<?> componentType, int... dimensions)
145 throws IllegalArgumentException, NegativeArraySizeException {
146 StringBuilder sig = new StringBuilder();
147 for (int i = 1; i < dimensions.length; i++) {
150 sig.append(findSignature(componentType));
151 return multiNewArray(sig.toString(), dimensions, 0);
155 * Returns the length of the specified array object, as an {@code int}.
157 * @param array the array
158 * @return the length of the array
159 * @exception IllegalArgumentException if the object argument is not
162 public static int getLength(Object array)
163 throws IllegalArgumentException {
164 if (!array.getClass().isArray()) {
165 throw new IllegalArgumentException("Argument is not an array");
167 return length(array);
170 @JavaScriptBody(args = { "arr" }, body = "return arr.length;")
171 private static native int length(Object arr);
174 * Returns the value of the indexed component in the specified
175 * array object. The value is automatically wrapped in an object
176 * if it has a primitive type.
178 * @param array the array
179 * @param index the index
180 * @return the (possibly wrapped) value of the indexed component in
181 * the specified array
182 * @exception NullPointerException If the specified object is null
183 * @exception IllegalArgumentException If the specified object is not
185 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
186 * argument is negative, or if it is greater than or equal to the
187 * length of the specified array
189 public static Object get(Object array, int index)
190 throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
191 final Class<?> t = array.getClass().getComponentType();
192 if (t.isPrimitive()) {
193 return fromPrimitive(t, array, index);
195 return ((Object[])array)[index];
200 * Returns the value of the indexed component in the specified
201 * array object, as a {@code boolean}.
203 * @param array the array
204 * @param index the index
205 * @return the value of the indexed component in the specified array
206 * @exception NullPointerException If the specified object is null
207 * @exception IllegalArgumentException If the specified object is not
208 * an array, or if the indexed element cannot be converted to the
209 * return type by an identity or widening conversion
210 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
211 * argument is negative, or if it is greater than or equal to the
212 * length of the specified array
215 public static native boolean getBoolean(Object array, int index)
216 throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
219 * Returns the value of the indexed component in the specified
220 * array object, as a {@code byte}.
222 * @param array the array
223 * @param index the index
224 * @return the value of the indexed component in the specified array
225 * @exception NullPointerException If the specified object is null
226 * @exception IllegalArgumentException If the specified object is not
227 * an array, or if the indexed element cannot be converted to the
228 * return type by an identity or widening conversion
229 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
230 * argument is negative, or if it is greater than or equal to the
231 * length of the specified array
234 public static byte getByte(Object array, int index)
235 throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
236 if (array.getClass().getComponentType() != Byte.TYPE) {
237 throw new IllegalArgumentException();
239 byte[] arr = (byte[]) array;
244 * Returns the value of the indexed component in the specified
245 * array object, as a {@code char}.
247 * @param array the array
248 * @param index the index
249 * @return the value of the indexed component in the specified array
250 * @exception NullPointerException If the specified object is null
251 * @exception IllegalArgumentException If the specified object is not
252 * an array, or if the indexed element cannot be converted to the
253 * return type by an identity or widening conversion
254 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
255 * argument is negative, or if it is greater than or equal to the
256 * length of the specified array
259 public static native char getChar(Object array, int index)
260 throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
263 * Returns the value of the indexed component in the specified
264 * array object, as a {@code short}.
266 * @param array the array
267 * @param index the index
268 * @return the value of the indexed component in the specified array
269 * @exception NullPointerException If the specified object is null
270 * @exception IllegalArgumentException If the specified object is not
271 * an array, or if the indexed element cannot be converted to the
272 * return type by an identity or widening conversion
273 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
274 * argument is negative, or if it is greater than or equal to the
275 * length of the specified array
278 public static short getShort(Object array, int index)
279 throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
280 final Class<?> t = array.getClass().getComponentType();
281 if (t == Short.TYPE) {
282 short[] arr = (short[]) array;
285 return getByte(array, index);
289 * Returns the value of the indexed component in the specified
290 * array object, as an {@code int}.
292 * @param array the array
293 * @param index the index
294 * @return the value of the indexed component in the specified array
295 * @exception NullPointerException If the specified object is null
296 * @exception IllegalArgumentException If the specified object is not
297 * an array, or if the indexed element cannot be converted to the
298 * return type by an identity or widening conversion
299 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
300 * argument is negative, or if it is greater than or equal to the
301 * length of the specified array
304 public static int getInt(Object array, int index)
305 throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
306 final Class<?> t = array.getClass().getComponentType();
307 if (t == Integer.TYPE) {
308 int[] arr = (int[]) array;
311 return getShort(array, index);
315 * Returns the value of the indexed component in the specified
316 * array object, as a {@code long}.
318 * @param array the array
319 * @param index the index
320 * @return the value of the indexed component in the specified array
321 * @exception NullPointerException If the specified object is null
322 * @exception IllegalArgumentException If the specified object is not
323 * an array, or if the indexed element cannot be converted to the
324 * return type by an identity or widening conversion
325 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
326 * argument is negative, or if it is greater than or equal to the
327 * length of the specified array
330 public static long getLong(Object array, int index)
331 throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
332 final Class<?> t = array.getClass().getComponentType();
333 if (t == Long.TYPE) {
334 long[] arr = (long[]) array;
337 return getInt(array, index);
341 * Returns the value of the indexed component in the specified
342 * array object, as a {@code float}.
344 * @param array the array
345 * @param index the index
346 * @return the value of the indexed component in the specified array
347 * @exception NullPointerException If the specified object is null
348 * @exception IllegalArgumentException If the specified object is not
349 * an array, or if the indexed element cannot be converted to the
350 * return type by an identity or widening conversion
351 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
352 * argument is negative, or if it is greater than or equal to the
353 * length of the specified array
356 public static float getFloat(Object array, int index)
357 throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
358 final Class<?> t = array.getClass().getComponentType();
359 if (t == Float.TYPE) {
360 float[] arr = (float[]) array;
363 return getLong(array, index);
367 * Returns the value of the indexed component in the specified
368 * array object, as a {@code double}.
370 * @param array the array
371 * @param index the index
372 * @return the value of the indexed component in the specified array
373 * @exception NullPointerException If the specified object is null
374 * @exception IllegalArgumentException If the specified object is not
375 * an array, or if the indexed element cannot be converted to the
376 * return type by an identity or widening conversion
377 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
378 * argument is negative, or if it is greater than or equal to the
379 * length of the specified array
382 public static double getDouble(Object array, int index)
383 throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
384 final Class<?> t = array.getClass().getComponentType();
385 if (t == Double.TYPE) {
386 double[] arr = (double[]) array;
389 return getFloat(array, index);
393 * Sets the value of the indexed component of the specified array
394 * object to the specified new value. The new value is first
395 * automatically unwrapped if the array has a primitive component
397 * @param array the array
398 * @param index the index into the array
399 * @param value the new value of the indexed component
400 * @exception NullPointerException If the specified object argument
402 * @exception IllegalArgumentException If the specified object argument
403 * is not an array, or if the array component type is primitive and
404 * an unwrapping conversion fails
405 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
406 * argument is negative, or if it is greater than or equal to
407 * the length of the specified array
409 public static void set(Object array, int index, Object value)
410 throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
411 if (array.getClass().getComponentType().isPrimitive()) {
412 throw new IllegalArgumentException();
414 Object[] arr = (Object[])array;
420 * Sets the value of the indexed component of the specified array
421 * object to the specified {@code boolean} value.
422 * @param array the array
423 * @param index the index into the array
424 * @param z the new value of the indexed component
425 * @exception NullPointerException If the specified object argument
427 * @exception IllegalArgumentException If the specified object argument
428 * is not an array, or if the specified value cannot be converted
429 * to the underlying array's component type by an identity or a
430 * primitive widening conversion
431 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
432 * argument is negative, or if it is greater than or equal to
433 * the length of the specified array
436 public static native void setBoolean(Object array, int index, boolean z)
437 throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
440 * Sets the value of the indexed component of the specified array
441 * object to the specified {@code byte} value.
442 * @param array the array
443 * @param index the index into the array
444 * @param b the new value of the indexed component
445 * @exception NullPointerException If the specified object argument
447 * @exception IllegalArgumentException If the specified object argument
448 * is not an array, or if the specified value cannot be converted
449 * to the underlying array's component type by an identity or a
450 * primitive widening conversion
451 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
452 * argument is negative, or if it is greater than or equal to
453 * the length of the specified array
456 public static void setByte(Object array, int index, byte b)
457 throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
458 Class<?> t = array.getClass().getComponentType();
459 if (t == Byte.TYPE) {
460 byte[] arr = (byte[]) array;
463 setShort(array, index, b);
468 * Sets the value of the indexed component of the specified array
469 * object to the specified {@code char} value.
470 * @param array the array
471 * @param index the index into the array
472 * @param c the new value of the indexed component
473 * @exception NullPointerException If the specified object argument
475 * @exception IllegalArgumentException If the specified object argument
476 * is not an array, or if the specified value cannot be converted
477 * to the underlying array's component type by an identity or a
478 * primitive widening conversion
479 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
480 * argument is negative, or if it is greater than or equal to
481 * the length of the specified array
484 public static native void setChar(Object array, int index, char c)
485 throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
488 * Sets the value of the indexed component of the specified array
489 * object to the specified {@code short} value.
490 * @param array the array
491 * @param index the index into the array
492 * @param s the new value of the indexed component
493 * @exception NullPointerException If the specified object argument
495 * @exception IllegalArgumentException If the specified object argument
496 * is not an array, or if the specified value cannot be converted
497 * to the underlying array's component type by an identity or a
498 * primitive widening conversion
499 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
500 * argument is negative, or if it is greater than or equal to
501 * the length of the specified array
504 public static void setShort(Object array, int index, short s)
505 throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
506 Class<?> t = array.getClass().getComponentType();
507 if (t == Short.TYPE) {
508 short[] arr = (short[]) array;
511 setInt(array, index, s);
517 * Sets the value of the indexed component of the specified array
518 * object to the specified {@code int} value.
519 * @param array the array
520 * @param index the index into the array
521 * @param i the new value of the indexed component
522 * @exception NullPointerException If the specified object argument
524 * @exception IllegalArgumentException If the specified object argument
525 * is not an array, or if the specified value cannot be converted
526 * to the underlying array's component type by an identity or a
527 * primitive widening conversion
528 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
529 * argument is negative, or if it is greater than or equal to
530 * the length of the specified array
533 public static void setInt(Object array, int index, int i)
534 throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
535 Class<?> t = array.getClass().getComponentType();
536 if (t == Integer.TYPE) {
537 int[] arr = (int[]) array;
540 setLong(array, index, i);
545 * Sets the value of the indexed component of the specified array
546 * object to the specified {@code long} value.
547 * @param array the array
548 * @param index the index into the array
549 * @param l the new value of the indexed component
550 * @exception NullPointerException If the specified object argument
552 * @exception IllegalArgumentException If the specified object argument
553 * is not an array, or if the specified value cannot be converted
554 * to the underlying array's component type by an identity or a
555 * primitive widening conversion
556 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
557 * argument is negative, or if it is greater than or equal to
558 * the length of the specified array
561 public static void setLong(Object array, int index, long l)
562 throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
563 Class<?> t = array.getClass().getComponentType();
564 if (t == Long.TYPE) {
565 long[] arr = (long[]) array;
568 setFloat(array, index, l);
573 * Sets the value of the indexed component of the specified array
574 * object to the specified {@code float} value.
575 * @param array the array
576 * @param index the index into the array
577 * @param f the new value of the indexed component
578 * @exception NullPointerException If the specified object argument
580 * @exception IllegalArgumentException If the specified object argument
581 * is not an array, or if the specified value cannot be converted
582 * to the underlying array's component type by an identity or a
583 * primitive widening conversion
584 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
585 * argument is negative, or if it is greater than or equal to
586 * the length of the specified array
589 public static void setFloat(Object array, int index, float f)
590 throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
591 Class<?> t = array.getClass().getComponentType();
592 if (t == Float.TYPE) {
593 float[] arr = (float[])array;
596 setDouble(array, index, f);
601 * Sets the value of the indexed component of the specified array
602 * object to the specified {@code double} value.
603 * @param array the array
604 * @param index the index into the array
605 * @param d the new value of the indexed component
606 * @exception NullPointerException If the specified object argument
608 * @exception IllegalArgumentException If the specified object argument
609 * is not an array, or if the specified value cannot be converted
610 * to the underlying array's component type by an identity or a
611 * primitive widening conversion
612 * @exception ArrayIndexOutOfBoundsException If the specified {@code index}
613 * argument is negative, or if it is greater than or equal to
614 * the length of the specified array
617 public static void setDouble(Object array, int index, double d)
618 throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
619 Class<?> t = array.getClass().getComponentType();
620 if (t == Double.TYPE) {
621 double[] arr = (double[])array;
624 throw new IllegalArgumentException("argument type mismatch");
632 @JavaScriptBody(args = { "primitive", "sig", "length" }, body =
633 "var arr = new Array(length);\n"
634 + "var value = primitive ? 0 : null;\n"
635 + "for(var i = 0; i < length; i++) arr[i] = value;\n"
636 + "arr.jvmName = sig;\n"
639 private static native Object newArray(boolean primitive, String sig, int length);
641 private static Object multiNewArray(String sig, int[] dims, int index)
642 throws IllegalArgumentException, NegativeArraySizeException {
643 if (dims.length == index + 1) {
644 return newArray(sig.length() == 2, sig, dims[index]);
646 Object arr = newArray(false, sig, dims[index]);
647 String compsig = sig.substring(1);
648 int len = getLength(arr);
649 for (int i = 0; i < len; i++) {
650 setArray(arr, i, multiNewArray(compsig, dims, index + 1));
654 private static Object fromPrimitive(Class<?> t, Object array, int index) {
655 return Method.fromPrimitive(t, atArray(array, index));
658 @JavaScriptBody(args = { "array", "index" }, body = "return array[index];")
659 private static native Object atArray(Object array, int index);
661 @JavaScriptBody(args = { "array", "index", "v" }, body = "array[index] = v;")
662 private static native Object setArray(Object array, int index, Object v);