If I have
public <T> doSomething(T[] array) { }
how can I get T.class
from array
?
If I do array.getClass()
that gets me T[].class
instead.
The Arrays class in java. util package is a part of the Java Collection Framework. This class provides static methods to dynamically create and access Java arrays. It consists of only static methods and the methods of Object class.
get() is an inbuilt method in Java and is used to return the element at a given index from the specified Array. Parameters : This method accepts two mandatory parameters: array: The object array whose index is to be returned. index: The particular index of the given array.
Use this:
array.getClass().getComponentType()
Returns the
Class
representing the component type of an array. If this class does not represent an array class this method returnsnull
.
Reference:
Class.getComponentType()
Is there a way I can cast to Class from Class returned by getComponentType() without getting a compiler warning?
take this method:
public <T> void doSomething(final T[] array) throws Exception{ final Class<? extends Object[]> arrayClass = array.getClass(); final Class<?> componentType = arrayClass.getComponentType(); final T newInstance = (T) componentType.newInstance(); }
Here's the generated byte code:
public void doSomething(java.lang.Object[] array) throws java.lang.Exception; 0 aload_1 [array] 1 invokevirtual java.lang.Object.getClass() : java.lang.Class [21] 4 astore_2 [arrayClass] 5 aload_2 [arrayClass] 6 invokevirtual java.lang.Class.getComponentType() : java.lang.Class [25] 9 astore_3 [componentType] 10 aload_3 [componentType] 11 invokevirtual java.lang.Class.newInstance() : java.lang.Object [30] 14 astore 4 [newInstance] 16 return
As you can see, the parameter type is erased to Object[], so the compiler has no way to know what T is. Yes, the compiler could use array.getClass().getComponentType()
, but that would sometimes fail miserably because you can do stuff like this:
Object[] arr = new String[] { "a", "b", "c" }; Integer[] integerArray = (Integer[]) arr; doSomething(integerArray);
(In this case array.getClass().getComponentType()
returns String.class
, but T
stands for Integer
. Yes, this is legal and does not generate compiler warnings.)
If you want to do this for multi-dimensional arrays the following recursive code will work
Class<?> getArrayType(Object array) { Object element = Array.get(array, 0); if (element.getClass().isArray()) { return getArrayType(element); } else { return array.getClass().getComponentType(); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With