11

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

4

8 回答 8

16

数组(例如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 使用类型擦除,因此信息在运行时会丢失。

您可以根据元素的类型猜测声明的集合类型:

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
    }
}
于 2013-07-12T05:37:48.070 回答
6

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

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

type然后将是任何基本类型。

如果objisdouble[][][][][][]或 justdouble[]或其他东西,这将起作用。

至于泛型,那些在<and中的东西>。发生类型擦除,这意味着您无法确定它们ArrayList本身的类型。

于 2013-07-12T05:43:02.707 回答
2

在数组的情况下,它可以通过 , 的类型来识别array(例如arrayofint[][]总是会给你int.

在 的情况下ArrayList,如果您ArrayList是异构对象,那么get(i)将始终为您提供 type 的元素Object。要知道它的类,你可以getClass()使用Object.

于 2013-07-12T05:35:03.423 回答
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 {

    }

希望能帮助到你

于 2013-07-12T06:44:00.560 回答
0

是的,那些被称为泛型。但最好认为它强制 Arraylist 只保存“点”对象。

于 2013-07-12T05:33:52.153 回答
0

有两种方法可以做到这一点:

  1. 使用instanceof运算符。

  2. 调用getClass()对象(确保首先检查 null)。

为此,您还可以参考我发现的内容:http: //docs.oracle.com/javase/tutorial/reflect/class/classNew.html

于 2013-07-12T05:36:03.323 回答
0

您可以获得 Array 的基本类型:

Object obj = new Long[0];
Class ofArray = obj.getClass().getComponentType();

对于 Collection 类型,可以使用 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);
    }
    ...
}
于 2013-07-12T05:42:47.410 回答
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());
    }   
于 2013-07-12T05:43:29.647 回答