请问如何确定泛型类型的类?

如何确定泛型类型的类?

我正在创建一个泛型类,在其中一个方法中,我需要知道当前使用的泛型类型的类。原因是我调用的方法之一期望这是一个参数。

例子:

public class MyGenericClass<T> {
  public void doSomething() {
    // Snip...
    // Call to a 3rd party lib
    T bean = (T)someObject.create(T.class);
    // Snip...
  }}

显然,上面的示例不起作用,并导致以下错误:类型参数T的非法类文字。

我的问题是:有人知道一个很好的替代方案或解决办法吗?



动漫人物
浏览 369回答 3
3回答

摇曳的蔷薇

同样的问题:一般信息在运行时被删除,无法恢复。解决方法是在静态方法的参数中传递类T:public&nbsp;class&nbsp;MyGenericClass<T>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;final&nbsp;Class<T>&nbsp;clazz; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;<U>&nbsp;MyGenericClass<U>&nbsp;createMyGeneric(Class<U>&nbsp;clazz)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;MyGenericClass<U>(clazz); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;MyGenericClass(Class<T>&nbsp;clazz)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.clazz&nbsp;=&nbsp;clazz; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;doSomething()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;instance&nbsp;=&nbsp;clazz.newInstance(); &nbsp;&nbsp;&nbsp;&nbsp;}}很丑,但很管用。

慕少森

我刚刚提到了这个解决方案:import java.lang.reflect.ParameterizedType;public abstract class A<B> {&nbsp; &nbsp; public Class<B> g() throws Exception {&nbsp; &nbsp; &nbsp; &nbsp; ParameterizedType superclass =&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (ParameterizedType) getClass().getGenericSuperclass();&nbsp; &nbsp; &nbsp; &nbsp; return (Class<B>) superclass.getActualTypeArguments()[0];&nbsp; &nbsp; }}如果A由子类提供具体类型:new A<String>() {}.g() // this will workclass B extends A<String> {}new B().g() // this will workclass C<T> extends A<T> {}new C<String>().g() // this will NOT work

精慕HU

不幸的是,Christoph的解决方案只在非常有限的情况下起作用。[编辑:正如下面的评论,我不再记得我对这句话的推理,这很可能是错误的:“注意,这只会在抽象类中起作用,首先。”下一个困难是g()的直接子类工作。A..不过,我们可以解决这个问题:private&nbsp;Class<?>&nbsp;extractClassFromType(Type&nbsp;t)&nbsp;throws&nbsp;ClassCastException&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(t&nbsp;instanceof&nbsp;Class<?>)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(Class<?>)t; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(Class<?>)((ParameterizedType)t).getRawType();}public&nbsp;Class<B>&nbsp;g()&nbsp;throws&nbsp;ClassCastException&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;Class<?>&nbsp;superClass&nbsp;=&nbsp;getClass();&nbsp;//&nbsp;initial&nbsp;value &nbsp;&nbsp;&nbsp;&nbsp;Type&nbsp;superType; &nbsp;&nbsp;&nbsp;&nbsp;do&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;superType&nbsp;=&nbsp;superClass.getGenericSuperclass(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;superClass&nbsp;=&nbsp;extractClassFromType(superType); &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;while&nbsp;(!&nbsp;(superClass.equals(A.class))); &nbsp;&nbsp;&nbsp;&nbsp;Type&nbsp;actualArg&nbsp;=&nbsp;((ParameterizedType)superType).getActualTypeArguments()[0]; &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(Class<B>)extractClassFromType(actualArg);}这将在许多实际情况下起作用,但并非总是如此。考虑:public&nbsp;class&nbsp;Foo<U,T&nbsp;extends&nbsp;Collection<?>>&nbsp;extends&nbsp;A<T>&nbsp;{}(new&nbsp;Foo<String,List<Object>>()&nbsp;{}).g();这将抛出一个ClassCastException,因为此处的类型参数不是Class或者是ParameterizedType一点也不,这是TypeVariable&nbsp;T..所以现在你会被困在想找出哪种类型T应该是用来代表兔子洞的,以此类推。我认为唯一合理的、一般的答案是类似于Nicolas最初的答案-一般来说,如果您的类需要实例化编译时未知的其他类的对象,那么类的用户需要显式地将该类文字(或者可能是一个工厂)传递给您的类,而不仅仅是依赖泛型。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java