/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package java.lang.reflect;
import java.lang.reflect.VMCommonLibrarySupport;
import org.jikesrvm.runtime.RuntimeEntrypoints;
/**
* This class must be implemented by the VM vendor. This class provides methods
* to dynamically create and access arrays.
*/
public final class Array {
/**
* Prevent this class from being instantiated
*/
private Array(){
//do nothing
}
/**
* Return the element of the array at the specified index. This reproduces
* the effect of <code>array[index]</code> If the array component is a
* base type, the result is automatically wrapped.
*
* @param array
* the array
* @param index
* the index
* @return the requested element, possibly wrapped
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static Object get(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
try {
return ((Object[])array)[index];
} catch (ClassCastException e) {
if (array instanceof int[]) {
return ((int[])array)[index];
}
if (array instanceof boolean[]) {
return ((boolean[])array)[index];
}
if (array instanceof float[]) {
return ((float[])array)[index];
}
if (array instanceof char[]) {
return ((char[])array)[index];
}
if (array instanceof double[]) {
return ((double[])array)[index];
}
if (array instanceof long[]) {
return ((long[])array)[index];
}
if (array instanceof short[]) {
return ((short[])array)[index];
}
if (array instanceof byte[]) {
return ((byte[])array)[index];
}
}
throw new IllegalArgumentException("Specified argument is not an array");
}
/**
* Return the element of the array at the specified index, converted to a
* boolean if possible. This reproduces the effect of
* <code>array[index]</code>
*
* @param array
* the array
* @param index
* the index
* @return the requested element
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the element cannot be
* converted to the requested type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static boolean getBoolean(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
try {
return ((boolean[])array)[index];
} catch (ClassCastException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
/**
* Return the element of the array at the specified index, converted to a
* byte if possible. This reproduces the effect of <code>array[index]</code>
*
* @param array
* the array
* @param index
* the index
* @return the requested element
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the element cannot be
* converted to the requested type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static byte getByte(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
try {
return ((byte[])array)[index];
} catch (ClassCastException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
/**
* Return the element of the array at the specified index, converted to a
* char if possible. This reproduces the effect of <code>array[index]</code>
*
* @param array
* the array
* @param index
* the index
* @return the requested element
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the element cannot be
* converted to the requested type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static char getChar(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
try {
return ((char[])array)[index];
} catch (ClassCastException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
/**
* Return the element of the array at the specified index, converted to a
* double if possible. This reproduces the effect of
* <code>array[index]</code>
*
* @param array
* the array
* @param index
* the index
* @return the requested element
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the element cannot be
* converted to the requested type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static double getDouble(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
if (array instanceof double[]) {
return ((double[])array)[index];
}
return getFloat(array, index);
}
/**
* Return the element of the array at the specified index, converted to a
* float if possible. This reproduces the effect of
* <code>array[index]</code>
*
* @param array
* the array
* @param index
* the index
* @return the requested element
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the element cannot be
* converted to the requested type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static float getFloat(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
if (array instanceof float[]) {
return ((float[])array)[index];
}
return getLong(array, index);
}
/**
* Return the element of the array at the specified index, converted to an
* int if possible. This reproduces the effect of <code>array[index]</code>
*
* @param array
* the array
* @param index
* the index
* @return the requested element
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the element cannot be
* converted to the requested type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static int getInt(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
if (array instanceof int[]) {
return ((int[])array)[index];
}
if (array instanceof char[]) {
return ((char[])array)[index];
}
return getShort(array, index);
}
/**
* Return the length of the array. This reproduces the effect of
* <code>array.length</code>
*
* @param array
* the array
* @return the length
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array
*/
public static int getLength(Object array)
throws IllegalArgumentException {
try {
return ((Object[])array).length;
} catch (ClassCastException e) {
if (array instanceof int[]) {
return ((int[])array).length;
}
if (array instanceof boolean[]) {
return ((boolean[])array).length;
}
if (array instanceof float[]) {
return ((float[])array).length;
}
if (array instanceof char[]) {
return ((char[])array).length;
}
if (array instanceof double[]) {
return ((double[])array).length;
}
if (array instanceof long[]) {
return ((long[])array).length;
}
if (array instanceof short[]) {
return ((short[])array).length;
}
if (array instanceof byte[]) {
return ((byte[])array).length;
}
}
throw new IllegalArgumentException("Specified argument is not an array");
}
/**
* Return the element of the array at the specified index, converted to a
* long if possible. This reproduces the effect of <code>array[index]</code>
*
* @param array
* the array
* @param index
* the index
* @return the requested element
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the element cannot be
* converted to the requested type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static long getLong(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
if (array instanceof long[]) {
return ((long[])array)[index];
}
return getInt(array, index);
}
/**
* Return the element of the array at the specified index, converted to a
* short if possible. This reproduces the effect of
* <code>array[index]</code>
*
* @param array
* the array
* @param index
* the index
* @return the requested element
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the element cannot be
* converted to the requested type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static short getShort(Object array, int index)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
if (array instanceof short[]) {
return ((short[])array)[index];
}
return getByte(array, index);
}
/**
* Return a new multidimensional array of the specified component type and
* dimensions. This reproduces the effect of
* <code>new componentType[d0][d1]...[dn]</code> for a dimensions array of {
* d0, d1, ... , dn }
*
* @param componentType
* the component type of the new array
* @param dimensions
* the dimensions of the new array
* @return the new array
* @throws java.lang.NullPointerException
* if the component type is null
* @throws java.lang.NegativeArraySizeException
* if any of the dimensions are negative
* @throws java.lang.IllegalArgumentException
* if the array of dimensions is of size zero, or exceeds the
* limit of the number of dimension for an array (currently
* 255)
*/
public static Object newInstance(Class<?> componentType, int[] dimensions)
throws NegativeArraySizeException, IllegalArgumentException {
return VMCommonLibrarySupport.createArray(componentType, dimensions);
}
/**
* Return a new array of the specified component type and length. This
* reproduces the effect of <code>new componentType[size]</code>
*
* @param componentType
* the component type of the new array
* @param size
* the length of the new array
* @return the new array
* @throws java.lang.NullPointerException
* if the component type is null
* @throws java.lang.NegativeArraySizeException
* if the size if negative
*/
public static Object newInstance(Class<?> componentType, int size)
throws NegativeArraySizeException {
return VMCommonLibrarySupport.createArray(componentType, size);
}
/**
* Set the element of the array at the specified index to the value. This
* reproduces the effect of <code>array[index] = value</code> If the array
* component is a base type, the value is automatically unwrapped
*
* @param array
* the array
* @param index
* the index
* @param value
* the new value
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the value cannot be
* converted to the array type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static void set(Object array, int index, Object value)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
if (array == null) {
throw new NullPointerException();
}
try {
((Object[])array)[index] = value;
return;
} catch (ClassCastException e) {
if (value instanceof Number) {
if (value instanceof Integer) {
setInt(array, index, ((Integer)value).intValue());
return;
} else if (value instanceof Float) {
setFloat(array, index, ((Float)value).floatValue());
return;
} else if (value instanceof Double) {
setDouble(array, index, ((Double)value).doubleValue());
return;
} else if (value instanceof Long) {
setLong(array, index, ((Long)value).longValue());
return;
} else if (value instanceof Short) {
setShort(array, index, ((Short)value).shortValue());
return;
} else if (value instanceof Byte) {
setByte(array, index, ((Byte)value).byteValue());
return;
}
} else if (value instanceof Boolean) {
setBoolean(array, index, ((Boolean)value).booleanValue());
return;
} else if (value instanceof Character) {
setChar(array, index, ((Character)value).charValue());
return;
}
} catch (ArrayStoreException e) {
throw new IllegalArgumentException(e.getMessage());
}
throw new IllegalArgumentException(
"Can not assign the specified value to the specified array component");
}
/**
* Set the element of the array at the specified index to the boolean value.
* This reproduces the effect of <code>array[index] = value</code>
*
* @param array
* the array
* @param index
* the index
* @param value
* the new value
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the value cannot be
* converted to the array type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static void setBoolean(Object array, int index, boolean value)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
try {
((boolean[])array)[index] = value;
} catch (ClassCastException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
/**
* Set the element of the array at the specified index to the byte value.
* This reproduces the effect of <code>array[index] = value</code>
*
* @param array
* the array
* @param index
* the index
* @param value
* the new value
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the value cannot be
* converted to the array type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static void setByte(Object array, int index, byte value)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
if (array instanceof byte[]) {
((byte[])array)[index] = value;
return;
}
setShort(array, index, value);
}
/**
* Set the element of the array at the specified index to the char value.
* This reproduces the effect of <code>array[index] = value</code>
*
* @param array
* the array
* @param index
* the index
* @param value
* the new value
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the value cannot be
* converted to the array type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static void setChar(Object array, int index, char value)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
if (array instanceof char[]) {
((char[])array)[index] = value;
return;
}
setInt(array, index, value);
}
/**
* Set the element of the array at the specified index to the double value.
* This reproduces the effect of <code>array[index] = value</code>
*
* @param array
* the array
* @param index
* the index
* @param value
* the new value
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the value cannot be
* converted to the array type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static void setDouble(Object array, int index, double value)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
try {
((double[])array)[index] = value;
} catch (ClassCastException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
/**
* Set the element of the array at the specified index to the float value.
* This reproduces the effect of <code>array[index] = value</code>
*
* @param array
* the array
* @param index
* the index
* @param value
* the new value
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the value cannot be
* converted to the array type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static void setFloat(Object array, int index, float value)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
if (array instanceof float[]) {
((float[])array)[index] = value;
return;
}
setDouble(array, index, value);
}
/**
* Set the element of the array at the specified index to the int value.
* This reproduces the effect of <code>array[index] = value</code>
*
* @param array
* the array
* @param index
* the index
* @param value
* the new value
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the value cannot be
* converted to the array type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static void setInt(Object array, int index, int value)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
if (array instanceof int[]) {
((int[])array)[index] = value;
return;
}
setLong(array, index, value);
}
/**
* Set the element of the array at the specified index to the long value.
* This reproduces the effect of <code>array[index] = value</code>
*
* @param array
* the array
* @param index
* the index
* @param value
* the new value
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the value cannot be
* converted to the array type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static void setLong(Object array, int index, long value)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
if (array instanceof long[]) {
((long[])array)[index] = value;
return;
}
setFloat(array, index, value);
}
/**
* Set the element of the array at the specified index to the short value.
* This reproduces the effect of <code>array[index] = value</code>
*
* @param array
* the array
* @param index
* the index
* @param value
* the new value
* @throws java.lang.NullPointerException
* if the array is null
* @throws java.lang.IllegalArgumentException
* if the array is not an array or the value cannot be
* converted to the array type by a widening conversion
* @throws java.lang.ArrayIndexOutOfBoundsException
* if the index is out of bounds -- negative or greater than
* or equal to the array length
*/
public static void setShort(Object array, int index, short value)
throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
if (array instanceof short[]) {
((short[])array)[index] = value;
return;
}
setInt(array, index, value);
}
}