Path: blob/master/jcl/src/java.base/share/classes/java/lang/reflect/Array.java
12521 views
/*[INCLUDE-IF Sidecar16]*/1package java.lang.reflect;23/*******************************************************************************4* Copyright (c) 1998, 2021 IBM Corp. and others5*6* This program and the accompanying materials are made available under7* the terms of the Eclipse Public License 2.0 which accompanies this8* distribution and is available at https://www.eclipse.org/legal/epl-2.0/9* or the Apache License, Version 2.0 which accompanies this distribution and10* is available at https://www.apache.org/licenses/LICENSE-2.0.11*12* This Source Code may also be made available under the following13* Secondary Licenses when the conditions for such availability set14* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU15* General Public License, version 2 with the GNU Classpath16* Exception [1] and GNU General Public License, version 2 with the17* OpenJDK Assembly Exception [2].18*19* [1] https://www.gnu.org/software/classpath/license.html20* [2] http://openjdk.java.net/legal/assembly-exception.html21*22* 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-exception23*******************************************************************************/2425/**26* This class provides methods to dynamically create and access arrays.27*28* @author OTI29* @version initial30*/31public final class Array {3233/**34* Prevent this class from being instantiated.35*/36private Array() {37}3839/**40* Return the element of the array at the specified index.41* This reproduces the effect of <code>array[index]</code>42* If the array component is a base type, the result is43* automatically wrapped.44*45* @param array the array46* @param index the index47* @return the requested element, possibly wrapped48* @exception java.lang.NullPointerException49* if the array is null50* @exception java.lang.IllegalArgumentException51* if the array is not an array52* @exception java.lang.ArrayIndexOutOfBoundsException53* if the index is out of bounds -- negative or greater than or equal to the array length54*/55public static Object get(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {56Class<?> arrayClass = array.getClass();57if (arrayClass == int[].class) {58return ((int[])array)[index];59} else if (arrayClass == boolean[].class) {60return ((boolean[])array)[index] ? Boolean.TRUE : Boolean.FALSE;61} else if (arrayClass == float[].class) {62return ((float[])array)[index];63} else if (arrayClass == char[].class) {64return ((char[])array)[index];65} else if (arrayClass == double[].class) {66return ((double[])array)[index];67} else if (arrayClass == long[].class) {68return ((long[])array)[index];69} else if (arrayClass == short[].class) {70return ((short[])array)[index];71} else if (arrayClass == byte[].class) {72/*[IF JAVA_SPEC_VERSION <= 11]*/73/* Avoiding Byte cache yields 5x performance improvement. */74return new Byte(((byte[])array)[index]);75/*[ELSE]*/76return ((byte[])array)[index];77/*[ENDIF] JAVA_SPEC_VERSION <= 11 */78} else {79try {80return ((Object[])array)[index];81} catch (ClassCastException e) {82throw new IllegalArgumentException(e.getMessage());83}84}85}8687/**88* Return the element of the array at the specified index,89* converted to a boolean if possible.90* This reproduces the effect of <code>array[index]</code>91*92* @param array the array93* @param index the index94* @return the requested element95* @exception java.lang.NullPointerException96* if the array is null97* @exception java.lang.IllegalArgumentException98* if the array is not an array or the element cannot be converted to the requested type by a widening conversion99* @exception java.lang.ArrayIndexOutOfBoundsException100* if the index is out of bounds -- negative or greater than or equal to the array length101*/102public static boolean getBoolean(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {103try {104return ((boolean[])array)[index];105} catch (ClassCastException e) {106throw new IllegalArgumentException(e.getMessage());107}108}109110/**111* Return the element of the array at the specified index,112* converted to a byte if possible.113* This reproduces the effect of <code>array[index]</code>114*115* @param array the array116* @param index the index117* @return the requested element118* @exception java.lang.NullPointerException119* if the array is null120* @exception java.lang.IllegalArgumentException121* if the array is not an array or the element cannot be converted to the requested type by a widening conversion122* @exception java.lang.ArrayIndexOutOfBoundsException123* if the index is out of bounds -- negative or greater than or equal to the array length124*/125public static byte getByte(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {126try {127return ((byte[])array)[index];128} catch (ClassCastException e) {129throw new IllegalArgumentException(e.getMessage());130}131}132133/**134* Return the element of the array at the specified index,135* converted to a char if possible.136* This reproduces the effect of <code>array[index]</code>137*138* @param array the array139* @param index the index140* @return the requested element141* @exception java.lang.NullPointerException142* if the array is null143* @exception java.lang.IllegalArgumentException144* if the array is not an array or the element cannot be converted to the requested type by a widening conversion145* @exception java.lang.ArrayIndexOutOfBoundsException146* if the index is out of bounds -- negative or greater than or equal to the array length147*/148public static char getChar(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {149try {150return ((char[])array)[index];151} catch (ClassCastException e) {152throw new IllegalArgumentException(e.getMessage());153}154}155156/**157* Return the element of the array at the specified index,158* converted to a double if possible.159* This reproduces the effect of <code>array[index]</code>160*161* @param array the array162* @param index the index163* @return the requested element164* @exception java.lang.NullPointerException165* if the array is null166* @exception java.lang.IllegalArgumentException167* if the array is not an array or the element cannot be converted to the requested type by a widening conversion168* @exception java.lang.ArrayIndexOutOfBoundsException169* if the index is out of bounds -- negative or greater than or equal to the array length170*/171public static double getDouble(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {172if (array.getClass() == double[].class) {173return ((double[])array)[index];174} else {175return getFloat(array, index);176}177}178179/**180* Return the element of the array at the specified index,181* converted to a float if possible.182* This reproduces the effect of <code>array[index]</code>183*184* @param array the array185* @param index the index186* @return the requested element187* @exception java.lang.NullPointerException188* if the array is null189* @exception java.lang.IllegalArgumentException190* if the array is not an array or the element cannot be converted to the requested type by a widening conversion191* @exception java.lang.ArrayIndexOutOfBoundsException192* if the index is out of bounds -- negative or greater than or equal to the array length193*/194public static float getFloat(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {195if (array.getClass() == float[].class) {196return ((float[])array)[index];197} else {198return getLong(array, index);199}200}201202/**203* Return the element of the array at the specified index,204* converted to an int if possible.205* This reproduces the effect of <code>array[index]</code>206*207* @param array the array208* @param index the index209* @return the requested element210* @exception java.lang.NullPointerException211* if the array is null212* @exception java.lang.IllegalArgumentException213* if the array is not an array or the element cannot be converted to the requested type by a widening conversion214* @exception java.lang.ArrayIndexOutOfBoundsException215* if the index is out of bounds -- negative or greater than or equal to the array length216*/217public static int getInt(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {218Class<?> arrayClass = array.getClass();219if (arrayClass == int[].class) {220return ((int[])array)[index];221} else if (arrayClass == char[].class) {222return ((char[])array)[index];223} else {224return getShort(array, index);225}226}227228/**229* Return the length of the array.230* This reproduces the effect of <code>array.length</code>231*232* @param array the array233* @return the length234* @exception java.lang.NullPointerException235* if the array is null236* @exception java.lang.IllegalArgumentException237* if the array is not an array238*/239public static int getLength(Object array) throws IllegalArgumentException {240Class<?> arrayClass = array.getClass();241if (arrayClass == int[].class) {242return ((int[])array).length;243} else if (arrayClass == boolean[].class) {244return ((boolean[])array).length;245} else if (arrayClass == float[].class) {246return ((float[])array).length;247} else if (arrayClass == char[].class) {248return ((char[])array).length;249} else if (arrayClass == double[].class) {250return ((double[])array).length;251} else if (arrayClass == long[].class) {252return ((long[])array).length;253} else if (arrayClass == short[].class) {254return ((short[])array).length;255} else if (arrayClass == byte[].class) {256return ((byte[])array).length;257} else {258try {259return ((Object[])array).length;260} catch (ClassCastException e) {261throw new IllegalArgumentException(e.getMessage());262}263}264}265266/**267* Return the element of the array at the specified index,268* converted to a long if possible.269* This reproduces the effect of <code>array[index]</code>270*271* @param array the array272* @param index the index273* @return the requested element274* @exception java.lang.NullPointerException275* if the array is null276* @exception java.lang.IllegalArgumentException277* if the array is not an array or the element cannot be converted to the requested type by a widening conversion278* @exception java.lang.ArrayIndexOutOfBoundsException279* if the index is out of bounds -- negative or greater than or equal to the array length280*/281public static long getLong(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {282if (array.getClass() == long[].class) {283return ((long[])array)[index];284} else {285return getInt(array, index);286}287}288289/**290* Return the element of the array at the specified index,291* converted to a short if possible.292* This reproduces the effect of <code>array[index]</code>293*294* @param array the array295* @param index the index296* @return the requested element297* @exception java.lang.NullPointerException298* if the array is null299* @exception java.lang.IllegalArgumentException300* if the array is not an array or the element cannot be converted to the requested type by a widening conversion301* @exception java.lang.ArrayIndexOutOfBoundsException302* if the index is out of bounds -- negative or greater than or equal to the array length303*/304public static short getShort(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {305if (array.getClass() == short[].class) {306return ((short[])array)[index];307} else {308return getByte(array, index);309}310}311312private static native Object multiNewArrayImpl(Class componentType, int dimensions, int[] dimensionsArray);313private static native Object newArrayImpl(Class componentType, int dimension);314315/**316* Return a new multidimensional array of the specified component type and dimensions.317* This reproduces the effect of <code>new componentType[d0][d1]...[dn]</code>318* for a dimensions array of { d0, d1, ... , dn }319*320* @param componentType the component type of the new array321* @param dimensions the dimensions of the new array322* @return the new array323* @exception java.lang.NullPointerException324* if the component type is null325* @exception java.lang.NegativeArraySizeException326* if any of the dimensions are negative327* @exception java.lang.IllegalArgumentException328* if componentType is Void.TYPE, or if the array of dimensions is of size zero, or exceeds the limit of329* the number of dimension for an array (currently 255)330*/331public static Object newInstance(Class<?> componentType, int... dimensions) throws NegativeArraySizeException, IllegalArgumentException332{333if (componentType == null) {334throw new NullPointerException();335}336337int length = dimensions.length;338if ((length < 1) || (length > 255) || (componentType == Void.TYPE)) {339throw new IllegalArgumentException();340}341342// Native is stack-oriented. Reverse the dimensions.343int[] reversed = new int[length];344345for (int i = 0; i < length; i++) {346if (dimensions[i] < 0) {347throw new NegativeArraySizeException(String.valueOf(dimensions[i]));348} else {349reversed[length - i - 1] = dimensions[i];350}351}352return multiNewArrayImpl(componentType, length, reversed);353}354355/**356* Return a new array of the specified component type and length.357* This reproduces the effect of <code>new componentType[size]</code>358*359* @param componentType the component type of the new array360* @param size the length of the new array361* @return the new array362* @exception java.lang.NullPointerException363* if the component type is null364* @exception java.lang.NegativeArraySizeException365* if the size if negative366* @exception java.lang.IllegalArgumentException367* if componentType is Void.TYPE, or the array dimension exceeds the limit of368* the number of dimension for an array (currently 255)369*/370public static Object newInstance(Class<?> componentType, int size) throws NegativeArraySizeException371{372if (componentType == null) {373throw new NullPointerException();374}375if (size < 0) {376throw new NegativeArraySizeException(String.valueOf(size));377}378if (componentType == Void.TYPE) {379throw new IllegalArgumentException();380}381return newArrayImpl(componentType, size);382}383384/**385* Set the element of the array at the specified index to the value.386* This reproduces the effect of <code>array[index] = value</code>387* If the array component is a base type, the value is automatically388* unwrapped389*390* @param array the array391* @param index the index392* @param value the new value393*394* @exception java.lang.NullPointerException395* if the array is null396* @exception java.lang.IllegalArgumentException397* if the array is not an array or the value cannot be converted to the array type by a widening conversion398* @exception java.lang.ArrayIndexOutOfBoundsException399* if the index is out of bounds -- negative or greater than or equal to the array length400*/401/*[REM both natives set and setImpl are in jclmax_2x]*/402public static void set(Object array, int index, Object value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {403final Class componentType = array.getClass().getComponentType();404if (componentType != null && componentType.isPrimitive()) {405/*[PR CMVC 87782] Behavior changed in 1.5*/406if (value == null) {407// trying to put null in a primitive array causes IllegalArgumentException in 1.5408// but a NullPointerException in 1.4409throw new IllegalArgumentException();410}411Class<?> valueClass = value.getClass();412if (valueClass == Integer.class) {413setInt(array, index, ((Integer)value).intValue());414} else if (valueClass == Float.class) {415setFloat(array, index, ((Float)value).floatValue());416} else if (valueClass == Double.class) {417setDouble(array, index, ((Double)value).doubleValue());418} else if (valueClass == Long.class) {419setLong(array, index, ((Long)value).longValue());420} else if (valueClass == Short.class) {421setShort(array, index, ((Short)value).shortValue());422} else if (valueClass == Byte.class) {423setByte(array, index, ((Byte)value).byteValue());424} else if (valueClass == Boolean.class) {425setBoolean(array, index, ((Boolean)value).booleanValue());426} else if (valueClass == Character.class) {427setChar(array, index, ((Character)value).charValue());428} else {429/* value is not primitive type */430throw new IllegalArgumentException();431}432} else {433try {434((Object[])array)[index] = value;435} catch (ClassCastException e) {436throw new IllegalArgumentException(e.getMessage());437} catch (ArrayStoreException e) {438throw new IllegalArgumentException(e.getMessage());439}440}441}442443/**444* Set the element of the array at the specified index to the boolean445* value. This reproduces the effect of <code>array[index] = value</code>446*447* @param array the array448* @param index the index449* @param value the new value450* @exception java.lang.NullPointerException451* if the array is null452* @exception java.lang.IllegalArgumentException453* if the array is not an array or the value cannot be converted to the array type by a widening conversion454* @exception java.lang.ArrayIndexOutOfBoundsException455* if the index is out of bounds -- negative or greater than or equal to the array length456*/457public static void setBoolean(Object array, int index, boolean value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {458try {459((boolean[])array)[index] = value;460} catch (ClassCastException e) {461throw new IllegalArgumentException(e.getMessage());462}463}464465/**466* Set the element of the array at the specified index to the byte467* value. This reproduces the effect of <code>array[index] = value</code>468*469* @param array the array470* @param index the index471* @param value the new value472* @exception java.lang.NullPointerException473* if the array is null474* @exception java.lang.IllegalArgumentException475* if the array is not an array or the value cannot be converted to the array type by a widening conversion476* @exception java.lang.ArrayIndexOutOfBoundsException477* if the index is out of bounds -- negative or greater than or equal to the array length478*/479public static void setByte(Object array, int index, byte value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {480if (array.getClass() == byte[].class) {481((byte[])array)[index] = value;482} else {483setShort(array, index, value);484}485}486487/**488* Set the element of the array at the specified index to the char489* value. This reproduces the effect of <code>array[index] = value</code>490*491* @param array the array492* @param index the index493* @param value the new value494* @exception java.lang.NullPointerException495* if the array is null496* @exception java.lang.IllegalArgumentException497* if the array is not an array or the value cannot be converted to the array type by a widening conversion498* @exception java.lang.ArrayIndexOutOfBoundsException499* if the index is out of bounds -- negative or greater than or equal to the array length500*/501public static void setChar(Object array, int index, char value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {502if (array.getClass() == char[].class) {503((char[])array)[index] = value;504} else {505setInt(array, index, value);506}507}508509/**510* Set the element of the array at the specified index to the double511* value. This reproduces the effect of <code>array[index] = value</code>512*513* @param array the array514* @param index the index515* @param value the new value516* @exception java.lang.NullPointerException517* if the array is null518* @exception java.lang.IllegalArgumentException519* if the array is not an array or the value cannot be converted to the array type by a widening conversion520* @exception java.lang.ArrayIndexOutOfBoundsException521* if the index is out of bounds -- negative or greater than or equal to the array length522*/523public static void setDouble(Object array, int index, double value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {524try {525((double[])array)[index] = value;526} catch (ClassCastException e) {527throw new IllegalArgumentException(e.getMessage());528}529}530531/**532* Set the element of the array at the specified index to the float533* value. This reproduces the effect of <code>array[index] = value</code>534*535* @param array the array536* @param index the index537* @param value the new value538* @exception java.lang.NullPointerException539* if the array is null540* @exception java.lang.IllegalArgumentException541* if the array is not an array or the value cannot be converted to the array type by a widening conversion542* @exception java.lang.ArrayIndexOutOfBoundsException543* if the index is out of bounds -- negative or greater than or equal to the array length544*/545public static void setFloat(Object array, int index, float value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {546if (array.getClass() == float[].class) {547((float[])array)[index] = value;548} else {549setDouble(array, index, value);550}551}552553/**554* Set the element of the array at the specified index to the int555* value. This reproduces the effect of <code>array[index] = value</code>556*557* @param array the array558* @param index the index559* @param value the new value560* @exception java.lang.NullPointerException561* if the array is null562* @exception java.lang.IllegalArgumentException563* if the array is not an array or the value cannot be converted to the array type by a widening conversion564* @exception java.lang.ArrayIndexOutOfBoundsException565* if the index is out of bounds -- negative or greater than or equal to the array length566*/567public static void setInt(Object array, int index, int value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {568if (array.getClass() == int[].class) {569((int[])array)[index] = value;570} else {571setLong(array, index, value);572}573}574575/**576* Set the element of the array at the specified index to the long577* value. This reproduces the effect of <code>array[index] = value</code>578*579* @param array the array580* @param index the index581* @param value the new value582* @exception java.lang.NullPointerException583* if the array is null584* @exception java.lang.IllegalArgumentException585* if the array is not an array or the value cannot be converted to the array type by a widening conversion586* @exception java.lang.ArrayIndexOutOfBoundsException587* if the index is out of bounds -- negative or greater than or equal to the array length588*/589public static void setLong(Object array, int index, long value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {590if (array.getClass() == long[].class) {591((long[])array)[index] = value;592} else {593setFloat(array, index, value);594}595}596597/**598* Set the element of the array at the specified index to the short599* value. This reproduces the effect of <code>array[index] = value</code>600*601* @param array the array602* @param index the index603* @param value the new value604* @exception java.lang.NullPointerException605* if the array is null606* @exception java.lang.IllegalArgumentException607* if the array is not an array or the value cannot be converted to the array type by a widening conversion608* @exception java.lang.ArrayIndexOutOfBoundsException609* if the index is out of bounds -- negative or greater than or equal to the array length610*/611public static void setShort(Object array, int index, short value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException {612if (array.getClass() == short[].class) {613((short[])array)[index] = value;614} else {615setInt(array, index, value);616}617}618}619620621