Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java: getting the class of the components of an array

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.

like image 302
Jason S Avatar asked Jan 19 '11 16:01

Jason S


People also ask

Do we have a array class in Java?

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.

How do I retrieve an element from an array?

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.


2 Answers

Component Type

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 returns null.

Reference:

  • Class.getComponentType()

Safe / Unsafe casting

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.)

like image 197
Sean Patrick Floyd Avatar answered Sep 22 '22 17:09

Sean Patrick Floyd


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();         }     }  
like image 34
James Mudd Avatar answered Sep 19 '22 17:09

James Mudd