Obtaining the Array Class of a Component Type

Obtaining the array Class of a component type

One thing that comes to mind is:

java.lang.reflect.Array.newInstance(componentType, 0).getClass();

But it creates an unnecessary instance.

Btw, this appears to work:

Class clazz = Class.forName("[L" + componentType.getName() + ";");

Here is test. It prints true:

Integer[] ar = new Integer[1];
Class componentType = ar.getClass().getComponentType();
Class clazz = Class.forName("[L" + componentType.getName() + ";");

System.out.println(clazz == ar.getClass());

The documentation of Class#getName() defines strictly the format of array class names:

If this class object represents a class of arrays, then the internal form of the name consists of the name of the element type preceded by one or more '[' characters representing the depth of the array nesting.

The Class.forName(..) approach won't directly work for primitives though - for them you'd have to create a mapping between the name (int) and the array shorthand - (I)

Getting the class of the components of an array

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

How can I get an element type class from an array type class?

You can use Class.getComponentType(), although there's no way for that method to give you generic type safety, so you'll need to do an unchecked cast to get a Class<T>:

public static <T> void doSomething(final Class<T[]> arrayType) {

@SuppressWarnings("unchecked")
final Class<T> componentType = (Class<T>)arrayType.getComponentType();

//etc.
}

For the reverse, see this question: Obtaining the array Class of a component type

How to get the Array Class for a given Class in Java?

Since Java 12, there is the arrayType() method on java.lang.Class. With that:

Class<?> arrayOfFooClass = fooClass.arrayType();

The implementation of Class.arrayType() just calls Arrays.newInstance(this, 0).getClass().

How to get the class associated to an array type?

The class of new MySpecialClass[0] is MySpecialClass[].class so you can use:

example.mySpecialMethod(MySpecialClass[].class)

When would the component type of an array type be an array type as well?

It is in this way that Java knows about multi-dimensional arrays. Consider the type

int[][][]

Its component type is int[][]. And the component type of int[][] is int[]. The component type of int[] is int. Here we reached a non-array type, which means that int is the element type of int[][][].

You might be wondering why the definition of "element type" is necessary. Well, one place where using "element type" is convenient in the spec is:

15.8.2 Class Literals

A class literal is an expression consisting of the name of a class, interface, array, or primitive type, or the pseudo-type void, followed by a '.' and the token class.

...

It is a compile-time error if the named type is a type variable (§4.4) or a parameterized type (§4.5) or an array whose element type is a type variable or parameterized type.

It doesn't make sense to say "array whose component type is a type variable or parameterized type" because that would only include T[] and List<Integer>[], but not T[][][][] or List<Integer>[][][][].

In Java, how do I dynamically determine the type of an array?

Just write

Class ofArray = o.getClass().getComponentType();

From the JavaDoc:

public Class<?> getComponentType()

Returns the Class representing the component type of an array. If this class does not represent an array class this method returns null.

Java Component Type of 2D Array

You can use a recursive method:

private static Class<?> getComponentTypeOfMultidimensionalArray(Class<?> arrayType) {
if (arrayType.isArray()) {
return getComponentTypeOfMultidimensionalArray(arrayType.getComponentType());
} else {
return arrayType;
}
}

Usage:

System.out.println(getComponentTypeOfMultidimensionalArray(int[][].class)); // int


Related Topics



Leave a reply



Submit