2012-08-07 48 views
3

我有一个函数:获取通用数组类

add(Collection<?> many) 

我这样称呼它:

Collection<NewClass> awa = new ArrayList<NewClass>(); 
add(awa) 

如何获得<?>类型?在那个功能?

many.getClass()给出ArrayList

为什么我需要这个?试图制作一个通用的DAO方法来添加的Collection。

编辑:

试过这样:

public static void add(Collection<?> many) { 
    Type typeArg = ((ParameterizedType)Testing.class.getGenericSuperclass()).getActualTypeArguments()[0]; 
    System.out.println(typeArg); 
} 

    Collection<NewClass> awa = new ArrayList<NewClass>(); 


    add(awa); 

遇到错误:

Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType 
+7

[类型擦除](http://docs.oracle.com/javase/tutorial/java/generics/erasure.html)将会很难。 – vcsjones 2012-08-07 14:10:41

+0

为什么你需要知道类型? – 2012-08-07 14:14:37

+0

@ Code-Guru:Hibernate通过类名向数据库添加元素 – Jaanus 2012-08-07 14:15:33

回答

4

many.getClass()ArrayList

当然,这听起来是对的。

如果您改为many.get(0).getClass(),该怎么办?在这里,我们询问元素,而不是容器,如果这是有道理的。我是C#呃,所以这可能不是100%正确的方法,但这是我在C#中采用的路线。

+1

这将工作,除非ArrayList为空。 – vcsjones 2012-08-07 14:18:23

+1

这样你就可以得到第一个元素的类型。如果列表中的元素不具有相同的类型,这可能很容易成为最具体的类型。您需要遍历所有元素并获得最通用的类​​型。 – 2012-08-07 14:28:44

+0

我认为他们会在所有元素中使用相同的类型,并且他会使用警戒条款,是的。 – jcolebrand 2012-08-07 14:48:02

1

你可以去解决这个问题,让你的方法一般,如:

public <T> void add(Collection<T> blah){} 

,如果它在不同的类,然后

DifferentClass dc = new DifferentClass(); 
dc.<NewClass>add(awa); 
你可以调用它,然后通过

this.<NewClass>add(awa); 

+0

好的,我如何获得T? – Jaanus 2012-08-07 14:25:30

+0

您使用类型调用它(请参阅编辑) – SamYonnou 2012-08-07 14:26:36

+0

为了正确,该方法和Call在不同的类中。它会起作用吗? – Jaanus 2012-08-07 14:28:04

1

为什么不尝试这样的事情:

public class Test { 

    Test() { 
    Collection<Integer> ints = new ArrayList<Integer>(); 
    add(ints, Integer.class); 
    Collection<String> strings = new ArrayList<String>(); 
    add(strings, String.class); 
    } 

    public final <T> void add(Collection<T> many, Class<T> type) { 
    System.out.println(type.getName()); 
    // do whatever needed. 
    } 

} 
+0

返回'java.lang.Class'。它对你有用吗? – Jaanus 2012-08-07 14:37:08

+0

只有一个小小的错误。这是正确的想法,由于类型擦除,您需要明确地在运行时提供类型。 – 2012-08-07 14:52:11

+0

这似乎令人难以置信的矫枉过正,因为你正在传递一个你可以从元素中推断出的类型的引用,不是吗?每个元素都带有一个类型,这确实是Java的一个重点。所以如果你有一个元素(函数被调用),那么你有一个类型。没有必要携带这些额外的行李。 – jcolebrand 2012-08-07 14:52:38

1

您可以检查运行时实际类型参数,但你只能通过从字段,方法,构造等反射API示例如下阅读:

import java.lang.reflect.Field; 
import java.lang.reflect.ParameterizedType; 
import java.lang.reflect.Type; 
import java.util.List; 


public class TypesSample { 

    public List<String> sampleList; 


    public static void main(String[] args) throws Exception { 
     Field f = TypesSample.class.getField("sampleList"); 
     ParameterizedType paramType = (ParameterizedType)f.getGenericType(); 
     Type typeArgument = paramType.getActualTypeArguments()[0]; 
     System.out.println(paramType.toString() + " with argument : " + typeArgument.toString()); 
    } 


} 

它说:java.util.List<java.lang.String> with argument : class java.lang.String

你赢了由于类型擦除,不会从对象引用中获取实际的参数类型。

//编辑:

这是你能为你的情况做什么:

abstract class GenericDAO<T> { 

    public void add(Collection<T> many) { 
     Type typeArg = ((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 
     System.out.println("This is a DAO for " + typeArg); 
    } 

} 

    // create DAOs that define what type parameter is 
class IntegerDAO extends GenericDAO<Integer> {} 
class StringDAO extends GenericDAO<String> {} 

然后:

GenericDAO<Integer> integerDAO = new IntegerDAO(); 
integerDAO.add(Arrays.asList(1,2,3)); 
GenericDAO<String> stringDAO = new StringDAO(); 
stringDAO.add(Arrays.asList("A","B","C")); 

说: 这是级Java一个DAO。 lang.Integer 这是一个java类的DAO。lang.String

但是您需要明确声明T是通过扩展泛型类。

+0

如何用方法参数'Collection param'来做到这一点? – 2012-08-07 14:57:50

+0

请参阅上例中的编辑 – 2012-08-07 15:03:11

+0

并未真正回答问题。回答一个不同的问题 – newacct 2012-08-07 20:01:29