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 returnsnull
.
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 returnsnull
.
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
Why Doesn't a Missing Annotation Cause a Classnotfoundexception at Runtime
How to Get the Session Object If I Have the Entity-Manager
How to Tune Tomcat 5.5 Jvm Memory Settings Without Using the Configuration Program
Filtering Database Rows with Spring-Data-JPA and Spring-Mvc
How to Set Classpath When I Use Javax.Tools.Javacompiler Compile the Source
Java: What's the Big-O Time of Declaring an Array of Size N
Stack with Find-Min/Find-Max More Efficient Than O(N)
Using Gson to Parse a JSON Array
Getting Mail from Gmail into Java Application Using Imap
Checked VS Unchecked Exception
Why Do == Comparisons with Integer.Valueof(String) Give Different Results for 127 and 128
How to Fix "The Expression of Type List Needs Unchecked Conversion...'
Cannot Find Firefox Binary in Path. Make Sure Firefox Is Installed