2013-07-12 35 views
10

假设我有一个数组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中完成吗?

+3

ArrayList的''是错误的,必须是ArrayList的''不要 – ajduke

+0

不知道他是怎么说“编译” – mattbdean

+3

这不是一个代码,因此它不会编译。 – Rishi

回答

13

阵列(如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>

无法获取类型参数。 Java使用type erasure,所以信息在运行时会丢失。

可以猜测基础上的类型元素的集合声明的类型:

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 
    } 
} 
+0

谢谢!奇迹般有效。 – wolf97084

0

是的,这些被称为泛型。但最好是认为它迫使Arraylist只持有“点”的对象。

2

在阵列的情况下,可以通过array的类型来确定的,(例如int[][]array总会给你int

ArrayList情况下,如果你的ArrayList是异质的对象,然后,get(i)会总是给你Object类型的元素以了解它的类,你可以使用的ObjectgetClass()方法

0

你可以得到阵列的基本类型为:

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); 
    } 
    ... 
} 
5

您可以使用类getComponentType()。例如。

public static final Class<?> getBaseType(Object obj) { 
    Class<?> type = obj.getClass(); 
    while (type.isArray()) { 
     type = type.getComponentType(); 
    } 
    return type; 
} 

type然后将是任何基类型。

如果objdouble[][][][][][]或只是double[],还是其他什么东西这将工作。

至于仿制药,那些东西在<>。发生类型擦除,这意味着您无法确定哪些类型来自ArrayList本身。

+0

汤姆看起来像借了我的答案,并将其纳入他自己的答案。 :) – Chase

+0

只为了完整性 - 我希望你不介意。无论如何,是不是我建议使用'isArray()'? – tom

+0

当然,我不介意。我发现它很有趣。但是我确实写了其余部分,我的方式来确定它是否也是一个数组。 – Chase

0

对于基本类型,您可以使用此代码:

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()); 
    } 
1

下面的代码工程...如您所问......

在这里,我已经使用

object.getClass()。getSimpleName()

为ArrayList的必须,因为您使用泛型添加特定类型的项目。然后得到它们并让它使用相同的getClass()。getSimpleName()方法。

public class ShowObjectType { 
     public static void main(String[] args) { 
      int arr[][] = { { 2, 3 }, { 4, 0 } }; 
      char[][] arr1 = { { 'a', 'c' }, { 'b', 'd' } }; 
      ArrayList<Integer> arr2 = new ArrayList<Integer>(); 
      arr2.add(4); 
      ArrayList<Point> arr3 = new ArrayList<Point>(); 
      arr3.add(new Point()); 
      System.out.println(arr.getClass().getSimpleName()); 
      System.out.println(arr1.getClass().getSimpleName()); 
       System.out.println(arr2.get(0).getClass().getSimpleName()); 
      System.out.println(arr3.get(0).getClass().getSimpleName()); 
     } 
    } 

    class Point { 

    } 

希望它有助于

+0

这是更简单的方法,你可以实现你所要求的。 – artapart

+0

@tom我知道它不适用于具有空集合的泛型类型。但是这里提出的问题只是关于这个......所以我给出了一种答案。 – artapart