Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/jcl/src/java.base/share/classes/java/lang/reflect/Array.java
12521 views
1
/*[INCLUDE-IF Sidecar16]*/
2
package java.lang.reflect;
3
4
/*******************************************************************************
5
* Copyright (c) 1998, 2021 IBM Corp. and others
6
*
7
* This program and the accompanying materials are made available under
8
* the terms of the Eclipse Public License 2.0 which accompanies this
9
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
10
* or the Apache License, Version 2.0 which accompanies this distribution and
11
* is available at https://www.apache.org/licenses/LICENSE-2.0.
12
*
13
* This Source Code may also be made available under the following
14
* Secondary Licenses when the conditions for such availability set
15
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
16
* General Public License, version 2 with the GNU Classpath
17
* Exception [1] and GNU General Public License, version 2 with the
18
* OpenJDK Assembly Exception [2].
19
*
20
* [1] https://www.gnu.org/software/classpath/license.html
21
* [2] http://openjdk.java.net/legal/assembly-exception.html
22
*
23
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
24
*******************************************************************************/
25
26
/**
27
* This class provides methods to dynamically create and access arrays.
28
*
29
* @author OTI
30
* @version initial
31
*/
32
public final class Array {
33
34
/**
35
* Prevent this class from being instantiated.
36
*/
37
private Array() {
38
}
39
40
/**
41
* Return the element of the array at the specified index.
42
* This reproduces the effect of <code>array[index]</code>
43
* If the array component is a base type, the result is
44
* automatically wrapped.
45
*
46
* @param array the array
47
* @param index the index
48
* @return the requested element, possibly wrapped
49
* @exception java.lang.NullPointerException
50
* if the array is null
51
* @exception java.lang.IllegalArgumentException
52
* if the array is not an array
53
* @exception java.lang.ArrayIndexOutOfBoundsException
54
* if the index is out of bounds -- negative or greater than or equal to the array length
55
*/
56
public static Object get(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
57
Class<?> arrayClass = array.getClass();
58
if (arrayClass == int[].class) {
59
return ((int[])array)[index];
60
} else if (arrayClass == boolean[].class) {
61
return ((boolean[])array)[index] ? Boolean.TRUE : Boolean.FALSE;
62
} else if (arrayClass == float[].class) {
63
return ((float[])array)[index];
64
} else if (arrayClass == char[].class) {
65
return ((char[])array)[index];
66
} else if (arrayClass == double[].class) {
67
return ((double[])array)[index];
68
} else if (arrayClass == long[].class) {
69
return ((long[])array)[index];
70
} else if (arrayClass == short[].class) {
71
return ((short[])array)[index];
72
} else if (arrayClass == byte[].class) {
73
/*[IF JAVA_SPEC_VERSION <= 11]*/
74
/* Avoiding Byte cache yields 5x performance improvement. */
75
return new Byte(((byte[])array)[index]);
76
/*[ELSE]*/
77
return ((byte[])array)[index];
78
/*[ENDIF] JAVA_SPEC_VERSION <= 11 */
79
} else {
80
try {
81
return ((Object[])array)[index];
82
} catch (ClassCastException e) {
83
throw new IllegalArgumentException(e.getMessage());
84
}
85
}
86
}
87
88
/**
89
* Return the element of the array at the specified index,
90
* converted to a boolean if possible.
91
* This reproduces the effect of <code>array[index]</code>
92
*
93
* @param array the array
94
* @param index the index
95
* @return the requested element
96
* @exception java.lang.NullPointerException
97
* if the array is null
98
* @exception java.lang.IllegalArgumentException
99
* if the array is not an array or the element cannot be converted to the requested type by a widening conversion
100
* @exception java.lang.ArrayIndexOutOfBoundsException
101
* if the index is out of bounds -- negative or greater than or equal to the array length
102
*/
103
public static boolean getBoolean(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
104
try {
105
return ((boolean[])array)[index];
106
} catch (ClassCastException e) {
107
throw new IllegalArgumentException(e.getMessage());
108
}
109
}
110
111
/**
112
* Return the element of the array at the specified index,
113
* converted to a byte if possible.
114
* This reproduces the effect of <code>array[index]</code>
115
*
116
* @param array the array
117
* @param index the index
118
* @return the requested element
119
* @exception java.lang.NullPointerException
120
* if the array is null
121
* @exception java.lang.IllegalArgumentException
122
* if the array is not an array or the element cannot be converted to the requested type by a widening conversion
123
* @exception java.lang.ArrayIndexOutOfBoundsException
124
* if the index is out of bounds -- negative or greater than or equal to the array length
125
*/
126
public static byte getByte(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
127
try {
128
return ((byte[])array)[index];
129
} catch (ClassCastException e) {
130
throw new IllegalArgumentException(e.getMessage());
131
}
132
}
133
134
/**
135
* Return the element of the array at the specified index,
136
* converted to a char if possible.
137
* This reproduces the effect of <code>array[index]</code>
138
*
139
* @param array the array
140
* @param index the index
141
* @return the requested element
142
* @exception java.lang.NullPointerException
143
* if the array is null
144
* @exception java.lang.IllegalArgumentException
145
* if the array is not an array or the element cannot be converted to the requested type by a widening conversion
146
* @exception java.lang.ArrayIndexOutOfBoundsException
147
* if the index is out of bounds -- negative or greater than or equal to the array length
148
*/
149
public static char getChar(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
150
try {
151
return ((char[])array)[index];
152
} catch (ClassCastException e) {
153
throw new IllegalArgumentException(e.getMessage());
154
}
155
}
156
157
/**
158
* Return the element of the array at the specified index,
159
* converted to a double if possible.
160
* This reproduces the effect of <code>array[index]</code>
161
*
162
* @param array the array
163
* @param index the index
164
* @return the requested element
165
* @exception java.lang.NullPointerException
166
* if the array is null
167
* @exception java.lang.IllegalArgumentException
168
* if the array is not an array or the element cannot be converted to the requested type by a widening conversion
169
* @exception java.lang.ArrayIndexOutOfBoundsException
170
* if the index is out of bounds -- negative or greater than or equal to the array length
171
*/
172
public static double getDouble(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
173
if (array.getClass() == double[].class) {
174
return ((double[])array)[index];
175
} else {
176
return getFloat(array, index);
177
}
178
}
179
180
/**
181
* Return the element of the array at the specified index,
182
* converted to a float if possible.
183
* This reproduces the effect of <code>array[index]</code>
184
*
185
* @param array the array
186
* @param index the index
187
* @return the requested element
188
* @exception java.lang.NullPointerException
189
* if the array is null
190
* @exception java.lang.IllegalArgumentException
191
* if the array is not an array or the element cannot be converted to the requested type by a widening conversion
192
* @exception java.lang.ArrayIndexOutOfBoundsException
193
* if the index is out of bounds -- negative or greater than or equal to the array length
194
*/
195
public static float getFloat(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
196
if (array.getClass() == float[].class) {
197
return ((float[])array)[index];
198
} else {
199
return getLong(array, index);
200
}
201
}
202
203
/**
204
* Return the element of the array at the specified index,
205
* converted to an int if possible.
206
* This reproduces the effect of <code>array[index]</code>
207
*
208
* @param array the array
209
* @param index the index
210
* @return the requested element
211
* @exception java.lang.NullPointerException
212
* if the array is null
213
* @exception java.lang.IllegalArgumentException
214
* if the array is not an array or the element cannot be converted to the requested type by a widening conversion
215
* @exception java.lang.ArrayIndexOutOfBoundsException
216
* if the index is out of bounds -- negative or greater than or equal to the array length
217
*/
218
public static int getInt(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
219
Class<?> arrayClass = array.getClass();
220
if (arrayClass == int[].class) {
221
return ((int[])array)[index];
222
} else if (arrayClass == char[].class) {
223
return ((char[])array)[index];
224
} else {
225
return getShort(array, index);
226
}
227
}
228
229
/**
230
* Return the length of the array.
231
* This reproduces the effect of <code>array.length</code>
232
*
233
* @param array the array
234
* @return the length
235
* @exception java.lang.NullPointerException
236
* if the array is null
237
* @exception java.lang.IllegalArgumentException
238
* if the array is not an array
239
*/
240
public static int getLength(Object array) throws IllegalArgumentException {
241
Class<?> arrayClass = array.getClass();
242
if (arrayClass == int[].class) {
243
return ((int[])array).length;
244
} else if (arrayClass == boolean[].class) {
245
return ((boolean[])array).length;
246
} else if (arrayClass == float[].class) {
247
return ((float[])array).length;
248
} else if (arrayClass == char[].class) {
249
return ((char[])array).length;
250
} else if (arrayClass == double[].class) {
251
return ((double[])array).length;
252
} else if (arrayClass == long[].class) {
253
return ((long[])array).length;
254
} else if (arrayClass == short[].class) {
255
return ((short[])array).length;
256
} else if (arrayClass == byte[].class) {
257
return ((byte[])array).length;
258
} else {
259
try {
260
return ((Object[])array).length;
261
} catch (ClassCastException e) {
262
throw new IllegalArgumentException(e.getMessage());
263
}
264
}
265
}
266
267
/**
268
* Return the element of the array at the specified index,
269
* converted to a long if possible.
270
* This reproduces the effect of <code>array[index]</code>
271
*
272
* @param array the array
273
* @param index the index
274
* @return the requested element
275
* @exception java.lang.NullPointerException
276
* if the array is null
277
* @exception java.lang.IllegalArgumentException
278
* if the array is not an array or the element cannot be converted to the requested type by a widening conversion
279
* @exception java.lang.ArrayIndexOutOfBoundsException
280
* if the index is out of bounds -- negative or greater than or equal to the array length
281
*/
282
public static long getLong(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
283
if (array.getClass() == long[].class) {
284
return ((long[])array)[index];
285
} else {
286
return getInt(array, index);
287
}
288
}
289
290
/**
291
* Return the element of the array at the specified index,
292
* converted to a short if possible.
293
* This reproduces the effect of <code>array[index]</code>
294
*
295
* @param array the array
296
* @param index the index
297
* @return the requested element
298
* @exception java.lang.NullPointerException
299
* if the array is null
300
* @exception java.lang.IllegalArgumentException
301
* if the array is not an array or the element cannot be converted to the requested type by a widening conversion
302
* @exception java.lang.ArrayIndexOutOfBoundsException
303
* if the index is out of bounds -- negative or greater than or equal to the array length
304
*/
305
public static short getShort(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
306
if (array.getClass() == short[].class) {
307
return ((short[])array)[index];
308
} else {
309
return getByte(array, index);
310
}
311
}
312
313
private static native Object multiNewArrayImpl(Class componentType, int dimensions, int[] dimensionsArray);
314
private static native Object newArrayImpl(Class componentType, int dimension);
315
316
/**
317
* Return a new multidimensional array of the specified component type and dimensions.
318
* This reproduces the effect of <code>new componentType[d0][d1]...[dn]</code>
319
* for a dimensions array of { d0, d1, ... , dn }
320
*
321
* @param componentType the component type of the new array
322
* @param dimensions the dimensions of the new array
323
* @return the new array
324
* @exception java.lang.NullPointerException
325
* if the component type is null
326
* @exception java.lang.NegativeArraySizeException
327
* if any of the dimensions are negative
328
* @exception java.lang.IllegalArgumentException
329
* if componentType is Void.TYPE, or if the array of dimensions is of size zero, or exceeds the limit of
330
* the number of dimension for an array (currently 255)
331
*/
332
public static Object newInstance(Class<?> componentType, int... dimensions) throws NegativeArraySizeException, IllegalArgumentException
333
{
334
if (componentType == null) {
335
throw new NullPointerException();
336
}
337
338
int length = dimensions.length;
339
if ((length < 1) || (length > 255) || (componentType == Void.TYPE)) {
340
throw new IllegalArgumentException();
341
}
342
343
// Native is stack-oriented. Reverse the dimensions.
344
int[] reversed = new int[length];
345
346
for (int i = 0; i < length; i++) {
347
if (dimensions[i] < 0) {
348
throw new NegativeArraySizeException(String.valueOf(dimensions[i]));
349
} else {
350
reversed[length - i - 1] = dimensions[i];
351
}
352
}
353
return multiNewArrayImpl(componentType, length, reversed);
354
}
355
356
/**
357
* Return a new array of the specified component type and length.
358
* This reproduces the effect of <code>new componentType[size]</code>
359
*
360
* @param componentType the component type of the new array
361
* @param size the length of the new array
362
* @return the new array
363
* @exception java.lang.NullPointerException
364
* if the component type is null
365
* @exception java.lang.NegativeArraySizeException
366
* if the size if negative
367
* @exception java.lang.IllegalArgumentException
368
* if componentType is Void.TYPE, or the array dimension exceeds the limit of
369
* the number of dimension for an array (currently 255)
370
*/
371
public static Object newInstance(Class<?> componentType, int size) throws NegativeArraySizeException
372
{
373
if (componentType == null) {
374
throw new NullPointerException();
375
}
376
if (size < 0) {
377
throw new NegativeArraySizeException(String.valueOf(size));
378
}
379
if (componentType == Void.TYPE) {
380
throw new IllegalArgumentException();
381
}
382
return newArrayImpl(componentType, size);
383
}
384
385
/**
386
* Set the element of the array at the specified index to the value.
387
* This reproduces the effect of <code>array[index] = value</code>
388
* If the array component is a base type, the value is automatically
389
* unwrapped
390
*
391
* @param array the array
392
* @param index the index
393
* @param value the new value
394
*
395
* @exception java.lang.NullPointerException
396
* if the array is null
397
* @exception java.lang.IllegalArgumentException
398
* if the array is not an array or the value cannot be converted to the array type by a widening conversion
399
* @exception java.lang.ArrayIndexOutOfBoundsException
400
* if the index is out of bounds -- negative or greater than or equal to the array length
401
*/
402
/*[REM both natives set and setImpl are in jclmax_2x]*/
403
public static void set(Object array, int index, Object value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
404
final Class componentType = array.getClass().getComponentType();
405
if (componentType != null && componentType.isPrimitive()) {
406
/*[PR CMVC 87782] Behavior changed in 1.5*/
407
if (value == null) {
408
// trying to put null in a primitive array causes IllegalArgumentException in 1.5
409
// but a NullPointerException in 1.4
410
throw new IllegalArgumentException();
411
}
412
Class<?> valueClass = value.getClass();
413
if (valueClass == Integer.class) {
414
setInt(array, index, ((Integer)value).intValue());
415
} else if (valueClass == Float.class) {
416
setFloat(array, index, ((Float)value).floatValue());
417
} else if (valueClass == Double.class) {
418
setDouble(array, index, ((Double)value).doubleValue());
419
} else if (valueClass == Long.class) {
420
setLong(array, index, ((Long)value).longValue());
421
} else if (valueClass == Short.class) {
422
setShort(array, index, ((Short)value).shortValue());
423
} else if (valueClass == Byte.class) {
424
setByte(array, index, ((Byte)value).byteValue());
425
} else if (valueClass == Boolean.class) {
426
setBoolean(array, index, ((Boolean)value).booleanValue());
427
} else if (valueClass == Character.class) {
428
setChar(array, index, ((Character)value).charValue());
429
} else {
430
/* value is not primitive type */
431
throw new IllegalArgumentException();
432
}
433
} else {
434
try {
435
((Object[])array)[index] = value;
436
} catch (ClassCastException e) {
437
throw new IllegalArgumentException(e.getMessage());
438
} catch (ArrayStoreException e) {
439
throw new IllegalArgumentException(e.getMessage());
440
}
441
}
442
}
443
444
/**
445
* Set the element of the array at the specified index to the boolean
446
* value. This reproduces the effect of <code>array[index] = value</code>
447
*
448
* @param array the array
449
* @param index the index
450
* @param value the new value
451
* @exception java.lang.NullPointerException
452
* if the array is null
453
* @exception java.lang.IllegalArgumentException
454
* if the array is not an array or the value cannot be converted to the array type by a widening conversion
455
* @exception java.lang.ArrayIndexOutOfBoundsException
456
* if the index is out of bounds -- negative or greater than or equal to the array length
457
*/
458
public static void setBoolean(Object array, int index, boolean value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
459
try {
460
((boolean[])array)[index] = value;
461
} catch (ClassCastException e) {
462
throw new IllegalArgumentException(e.getMessage());
463
}
464
}
465
466
/**
467
* Set the element of the array at the specified index to the byte
468
* value. This reproduces the effect of <code>array[index] = value</code>
469
*
470
* @param array the array
471
* @param index the index
472
* @param value the new value
473
* @exception java.lang.NullPointerException
474
* if the array is null
475
* @exception java.lang.IllegalArgumentException
476
* if the array is not an array or the value cannot be converted to the array type by a widening conversion
477
* @exception java.lang.ArrayIndexOutOfBoundsException
478
* if the index is out of bounds -- negative or greater than or equal to the array length
479
*/
480
public static void setByte(Object array, int index, byte value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
481
if (array.getClass() == byte[].class) {
482
((byte[])array)[index] = value;
483
} else {
484
setShort(array, index, value);
485
}
486
}
487
488
/**
489
* Set the element of the array at the specified index to the char
490
* value. This reproduces the effect of <code>array[index] = value</code>
491
*
492
* @param array the array
493
* @param index the index
494
* @param value the new value
495
* @exception java.lang.NullPointerException
496
* if the array is null
497
* @exception java.lang.IllegalArgumentException
498
* if the array is not an array or the value cannot be converted to the array type by a widening conversion
499
* @exception java.lang.ArrayIndexOutOfBoundsException
500
* if the index is out of bounds -- negative or greater than or equal to the array length
501
*/
502
public static void setChar(Object array, int index, char value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
503
if (array.getClass() == char[].class) {
504
((char[])array)[index] = value;
505
} else {
506
setInt(array, index, value);
507
}
508
}
509
510
/**
511
* Set the element of the array at the specified index to the double
512
* value. This reproduces the effect of <code>array[index] = value</code>
513
*
514
* @param array the array
515
* @param index the index
516
* @param value the new value
517
* @exception java.lang.NullPointerException
518
* if the array is null
519
* @exception java.lang.IllegalArgumentException
520
* if the array is not an array or the value cannot be converted to the array type by a widening conversion
521
* @exception java.lang.ArrayIndexOutOfBoundsException
522
* if the index is out of bounds -- negative or greater than or equal to the array length
523
*/
524
public static void setDouble(Object array, int index, double value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
525
try {
526
((double[])array)[index] = value;
527
} catch (ClassCastException e) {
528
throw new IllegalArgumentException(e.getMessage());
529
}
530
}
531
532
/**
533
* Set the element of the array at the specified index to the float
534
* value. This reproduces the effect of <code>array[index] = value</code>
535
*
536
* @param array the array
537
* @param index the index
538
* @param value the new value
539
* @exception java.lang.NullPointerException
540
* if the array is null
541
* @exception java.lang.IllegalArgumentException
542
* if the array is not an array or the value cannot be converted to the array type by a widening conversion
543
* @exception java.lang.ArrayIndexOutOfBoundsException
544
* if the index is out of bounds -- negative or greater than or equal to the array length
545
*/
546
public static void setFloat(Object array, int index, float value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
547
if (array.getClass() == float[].class) {
548
((float[])array)[index] = value;
549
} else {
550
setDouble(array, index, value);
551
}
552
}
553
554
/**
555
* Set the element of the array at the specified index to the int
556
* value. This reproduces the effect of <code>array[index] = value</code>
557
*
558
* @param array the array
559
* @param index the index
560
* @param value the new value
561
* @exception java.lang.NullPointerException
562
* if the array is null
563
* @exception java.lang.IllegalArgumentException
564
* if the array is not an array or the value cannot be converted to the array type by a widening conversion
565
* @exception java.lang.ArrayIndexOutOfBoundsException
566
* if the index is out of bounds -- negative or greater than or equal to the array length
567
*/
568
public static void setInt(Object array, int index, int value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
569
if (array.getClass() == int[].class) {
570
((int[])array)[index] = value;
571
} else {
572
setLong(array, index, value);
573
}
574
}
575
576
/**
577
* Set the element of the array at the specified index to the long
578
* value. This reproduces the effect of <code>array[index] = value</code>
579
*
580
* @param array the array
581
* @param index the index
582
* @param value the new value
583
* @exception java.lang.NullPointerException
584
* if the array is null
585
* @exception java.lang.IllegalArgumentException
586
* if the array is not an array or the value cannot be converted to the array type by a widening conversion
587
* @exception java.lang.ArrayIndexOutOfBoundsException
588
* if the index is out of bounds -- negative or greater than or equal to the array length
589
*/
590
public static void setLong(Object array, int index, long value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
591
if (array.getClass() == long[].class) {
592
((long[])array)[index] = value;
593
} else {
594
setFloat(array, index, value);
595
}
596
}
597
598
/**
599
* Set the element of the array at the specified index to the short
600
* value. This reproduces the effect of <code>array[index] = value</code>
601
*
602
* @param array the array
603
* @param index the index
604
* @param value the new value
605
* @exception java.lang.NullPointerException
606
* if the array is null
607
* @exception java.lang.IllegalArgumentException
608
* if the array is not an array or the value cannot be converted to the array type by a widening conversion
609
* @exception java.lang.ArrayIndexOutOfBoundsException
610
* if the index is out of bounds -- negative or greater than or equal to the array length
611
*/
612
public static void setShort(Object array, int index, short value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
613
if (array.getClass() == short[].class) {
614
((short[])array)[index] = value;
615
} else {
616
setInt(array, index, value);
617
}
618
}
619
}
620
621