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.
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:
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
public static Class<?> getArrayType(Object array) {
Object element = Array.get(array, 0);
if (element.getClass().isArray()) {
return getArrayType(element);
} else {
return array.getClass().getComponentType();
}
}
Maybe an old thread, but I would like to share a tested version I did with all your recomendations:
@NotNull
@SafeVarargs
public static <T> T coalesce(@NotNull T ... args) {
for(T i : args) {
if(i != null) {
return i;
}
}
T newInstance = null;
try {
final Class<? extends Object[]> arrayClass = args.getClass();
final Class<?> componentType = arrayClass.getComponentType();
newInstance = (T) componentType.newInstance();
}catch(Exception e) {
e.printStackTrace();
}
return newInstance;
}
Hope will be usefull to you!
Best regards!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.