如果没有参数,如何获得generics类?

我刚学会了这种精美的语法

Collections.emptyList() 

获取一个空的List ,其元素应该是String类型。 Java的源代码如下:

 public static final List EMPTY_LIST = new EmptyList(); : public static final  List emptyList() { return (List) EMPTY_LIST; } 

现在如果我以这种方式编写一个方法,其中generics类型没有出现在参数列表中,有什么方法可以访问变为T的实际类?

我说,到目前为止我的代码处理方法一直都是

 private  T get(String key, Class clazz) { // here I can do whatever I want with clazz, eg: return clazz.cast(value); } 

如果我删除了clazz参数,我就无法进行强制转换cast() 。 显然我能做到

  return (T) value; 

但是这给了我通常的警告Type safety: Unchecked cast from Object to T 好的, @SuppressWarnings("unchecked")在这里有所帮助,但实际上我想用该方法的预期返回类型做一些事情。 如果我添加一个局部变量

 T retValue; 

我必须用一些东西初始化它, null无济于事。 在我分配之后

 @SuppressWarnings("unchecked") T retValue = (T) value; 

我能做到,例如

 retValue.getClass().getName() 

但如果演员表失败,我最终没有关于T信息。

由于Java(或至少我的Java 6)在运行时不再具有通用信息,因此我目前无法想到这样做的方法。 有办法吗? 或者我必须坚持我的“旧”方法吗?

请注意,我列出的示例非常简单,没有多大意义。 我想在这里做更复杂的事情,但这超出了范围。

如果您希望在运行时使用generics类型,则需要将其作为字段或为特定类型组合创建类型的子类。

例如

 List list = new ArrayList() {}; // creates a generic sub-type final Class type = (Class) ((ParameterizedType) list.getClass() .getGenericSuperclass()).getActualTypeArguments()[0]; System.out.println(type); 

版画

 class java.lang.String 

不幸的是,你不能。 所有generics和类型参数都在运行时被擦除。 所以在运行时,你的T的类型就是Object

retValue.getClass().getName()将始终返回对象的运行时类型,而不是参数类型的类名。

如果你想获取参数类,除了使用你的第一个解决方案之外别无他法。 (也就是说,明确传递类对象。)

正如您所提到的,Javagenerics只是构建时间。 它们在运行时不使用。

因此,您使用的旧方法将是您实现此目标的唯一方法。

我发现从T获取Class有一个解决方案:

 public class Action{ } public Class getGenericType(Object action) throws ClassNotFoundException{ Type type = ((ParameterizedType)action.getClass().getGenericSuperclass()) .getActualTypeArguments()[0]; String sType[] = type.toString().split(" "); if(sType.length != 2) throw new ClassNotFoundException(); return Class.forName(sType[1]); } 

上面代码的用法:

 Action myAction = new Action(); getGenericType(myAction); 

我没有用原始类型(int,byte,boolean)测试它。

我认为它不是很快,但你不必将Class传递给构造函数。

编辑:

上面的用法不正确,因为Action不能使用通用超类。 通用超类只能用于inheritance类, class ActionWithParam extends Action{} 。 这就是我改变主意的原因,现在我建议将class参数传递给构造函数。 感谢newacct的纠正。