Определение типа объектов в коллекции или массиве
предположим, что у меня есть массив int[][] или массив char[][] или ArrayList. Есть ли способ в java узнать тип базового класса массива. Например:
int[][] gives output as int.
char[][] gives output as char.
ArrayList<Integer> gives output Integer.
ArrayList<Point> gives Point. (It should also work for a custom type)
можно ли это сделать на Java?
8 ответов
массивы (например,int[][]
)
вы можете получить тип компонента массива, используя getComponentType():
(new int[10][10]).getClass().getComponentType().getComponentType(); // int
для массивов произвольной глубины используйте цикл:
Object array = new int[10][][][];
Class<?> type = array.getClass();
while (type.isArray())
{
type = type.getComponentType();
}
assert type == Integer.TYPE;
Универсального Типа (например,ArrayList<Integer>
)
невозможно получить параметр type. Java использует стирания типа, поэтому информация теряется во время выполнения.
вы можете угадать объявленный тип коллекций на основе типов элементов:
import java.util.*;
public class CollectionTypeGuesser
{
static Set<Class<?>> supers(Class<?> c)
{
if (c == null) return new HashSet<Class<?>>();
Set<Class<?>> s = supers(c.getSuperclass());
s.add(c);
return s;
}
static Class<?> lowestCommonSuper(Class<?> a, Class<?> b)
{
Set<Class<?>> aSupers = supers(a);
while (!aSupers.contains(b))
{
b = b.getSuperclass();
}
return b;
}
static Class<?> guessElementType(Collection<?> collection)
{
Class<?> guess = null;
for (Object o : collection)
{
if (o != null)
{
if (guess == null)
{
guess = o.getClass();
}
else if (guess != o.getClass())
{
guess = lowestCommonSuper(guess, o.getClass());
}
}
}
return guess;
}
static class C1 { }
static class C2 extends C1 { }
static class C3A extends C2 { }
static class C3B extends C2 { }
public static void main(String[] args)
{
ArrayList<Integer> listOfInt = new ArrayList<Integer>();
System.out.println(guessElementType(listOfInt)); // null
listOfInt.add(42);
System.out.println(guessElementType(listOfInt)); // Integer
ArrayList<C1> listOfC1 = new ArrayList<C1>();
listOfC1.add(new C3A());
System.out.println(guessElementType(listOfC1)); // C3A
listOfC1.add(new C3B());
System.out.println(guessElementType(listOfC1)); // C2
listOfC1.add(new C1());
System.out.println(guessElementType(listOfC1)); // C1
}
}
вы можете использовать классы getComponentType()
. Например.
public static final Class<?> getBaseType(Object obj) {
Class<?> type = obj.getClass();
while (type.isArray()) {
type = type.getComponentType();
}
return type;
}
type
будет тогда любым базовым типом.
это будет работать, если obj
is double[][][][][][]
или просто double[]
, или что-то еще.
что касается дженериков, то эти вещи в <
и >
. Происходит стирание типа, то есть вы не можете определить, какой тип они из .
в случае массивов он может быть идентифицирован с помощью типа array
(например,array
of int[][]
всегда будет давать вам int
.
в случае ArrayList
, если ArrayList
тогда гетерогенные объекты,get(i)
всегда будет давать вам элемент типа Object
. Чтобы узнать его класс, вы можете использовать getClass()
метод Object
.
Да, они называются дженериками. Но лучше думать, что это заставляет Arraylist удерживать только "точечные" объекты.
два способа сделать это:
использовать
instanceof
оператора.вызов
getClass()
на объекте (сначала проверьте значение null).
для этого вы также можете сослаться на то, что я нашел: http://docs.oracle.com/javase/tutorial/reflect/class/classNew.html
Вы можете получить базовый тип массива как:
Object obj = new Long[0];
Class ofArray = obj.getClass().getComponentType();
для типа коллекции можно использовать метод getClass() или instanceof. Например:
ArrayList<Object> list = ...;
for (Object obj : list) {
if (obj instanceof String) {
...
}
}
for (Object o : list) {
if (o.getClass().equals(Integer.TYPE)) {
handleInt((int)o);
}
else if (o.getClass().equals(String.class)) {
handleString((String)o);
}
...
}
для примитивных типов вы можете использовать этот код:
public static void main(String[] args) {
int arr[] = {1,2,3};
int arr2[][] = {{1},{2},{3}};
char arrc[] = {'v', 'c', 'r'};
System.out.println(arr.getClass().getCanonicalName());
System.out.println(arr2.getClass().getCanonicalName());
System.out.println(arrc.getClass().getCanonicalName());
}
выход:
int[]
int[][]
char[]
для ArrayList, если вам нужно работать с его элементами (если список не пуст) вы можете проверить тип первого элемента
ArrayList<Integer> arrInt = new ArrayList<Integer>();
arrInt.add(100);
if (arrInt instanceof List && arrInt.size() > 0) {
System.out.println(arrInt.get(0).getClass().getCanonicalName());
}