获取Java泛型的类和泛型接口实现

5
我想创建一个基本上看起来像这样的类:
public class MyClass<T implements Serializable) {

   void function() {
      Class c = T.class;
   }
}

两个错误:
- 我无法调用 T.class,即使我可以使用任何其他对象类型
- 我无法以这种方式强制执行T实现Serializable

我该如何解决我的两个泛型问题?

干杯

Nik


你能否加入一个实际想要实现的例子? - Zed
5个回答

7
你无法获取类型。
泛型是使用称为type-erasure的东西实现的。
当实例化泛型类型时,编译器通过一种称为类型擦除的技术来翻译那些类型 - 这是一种过程,其中编译器删除与类或方法中的类型参数和类型参数相关的所有信息。类型擦除使使用泛型的Java应用程序能够与在泛型之前创建的Java库和应用程序保持二进制兼容性。
本质上,类型信息由编译器使用并丢弃,因此在运行时不可用。
关于强制执行T implements Serializable,您只需要以下内容:
public class MyClass<T extends Serializable>)
{
  public void function(T obj) 
  {
    ...
  }
}

这只是指“is a”关系,因此实现了Serializable接口的类就是Serializable,并且可以传递给函数。

1
非常感谢您的详细解释,我现在明白了为什么它不起作用,并且我已经通过gjrwebber提出的解决方法解决了我的实际问题。非常感谢! :-) - niklassaers

5
你需要这样做:
public class MyClass<T implements Serializable) {

   void function(Class<T> tc) {
      ...
   }
}

基本上,你必须在运行时传入类才能看到它。你也可以像这样做:

public class MyClass<T implements Serializable) {
   Class<T> ct; 
   public MyClass(Class<T> ct){this.ct = ct;}

   void function() {
       ... //you know what the class is here
   }
}

这有点烦人,但总体来说并不是太麻烦。

涉及IT技术相关内容。

3

大致上应该是这样的。

private Class<T> dataType;
Type type = getClass().getGenericSuperclass();
if (type instanceof ParameterizedType) {
    ParameterizedType paramType = (ParameterizedType) type;
    dataType = (Class<T>) paramType.getActualTypeArguments()[0];
} else if (type instanceof Class) {
    dataType = (Class<T>) type;
}

感谢提供的解决方法,它帮助我解决了问题,其他答案也帮助我理解了问题。 :-) 你们是最棒的! :-) - niklassaers
9
我遇到了一个sun.reflect.generics.reflectiveObjects.TypeVariableImpl无法强制转换为java.lang.Class的问题,我错了什么? - Eran Medan

1
因为Java在运行时实际上并不知道T是哪个类,所以你不能使用T.class。
所有这些信息都在编译时丢失了。
要获取T的类对象,可以在T的实例上调用getClass()(如果您有一个实例),或要求用户将类对象作为参数传递给function,如下所示:
void function(Class<T> c)

泛型参数边界的语法是 <T extends Serializable> 而不是 <T implements Serializable>。 - Tadeusz Kopec for Ukraine
感谢您的快速反馈。(1)问题在于,在我的通用函数中,我想使用以T.class作为输入参数的函数。如果我不能这样做,一个不太好的解决方法是实例化一个类T的对象,但是据我所知,我也不能说“new T()”,因为类型擦除的原因?(2)哎呀,没看到打字错误。但是,我的Java编译器声称它期望我在写implements时使用逗号,这就是我所指的。编辑:谢谢tkopec,extends效果更好,我不知道我可以扩展一个接口。 - niklassaers

0

这是不可能的,除非使用一些技巧。 Java Generics FAQ 提供了一个解决方法的思路。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接