【问题标题】:Type Erasure in Generics泛型中的类型擦除
【发布时间】:2012-09-09 18:36:36
【问题描述】:

以下代码在类型擦除后在运行时看起来是什么:

public class Test<T> {

T lst;
List<T> list1;
void meth() throws InstantiationException, IllegalAccessException{  T res = (T)lst.getClass().newInstance();}

static <S> void meth(S t){}
}  
class TestUse{
public static void main(String[] args) {
Test<Integer> gint = new Test<Integer>();
Test<String> gstr = new Test<String>();
gint.meth();
gstr.meth();

}   

【问题讨论】:

  • 你还没有定义Genrics类。
  • 类型擦除后Genrics&lt;Integer&gt; gint = new Genrics&lt;Integer&gt;(); 看起来像Genrics gint = new Genrics();
  • 它在运行时“看起来不像”任何东西,因为它不能编译。

标签: java generics type-erasure


【解决方案1】:

以下代码不起作用:

T res = (T)lst.getClass().newInstance();

因为在所有可能的情况下,T 在运行时都是 Object 类型。

一种解决方法是使用具有继承的泛型:

public abstract class Generic<T> {

    public abstract Class<T> getConcreteClass();

    public void doSomething() {
        Class<T> clazz = getConcreteClass();
        T t = clazz.newInstance();
        doSomethingWithT();
    }
}

public class ConcreteClass extends Generic<YourObject> {
    public Class<YourObject> getConcreteClass() {
        return YourObject.class;
    }
}

【讨论】:

  • @user1649415: 你还没有实例化 lst;它应该在调用 getClass() 时抛出 NullPointerException。
【解决方案2】:

我觉得是这样的

public class Test {

    Object lst;
    List list1;
    void meth() throws InstantiationException, IllegalAccessException{  
        Object res =lst.getCla ss().newInstance();
    }

   static void meth(Object t){
   }
}

class TestUse{
    public static void main(String[] args) {
        Genrics gint = new Genrics();
        Genrics gstr = new Genrics();
        gint.meth();
        gstr.meth();
    }   

虽然我认为这不会按现在的样子编译。没有 Genrics 类 - 或者是 Test 类。

【讨论】:

  • Test 类有一个无参数的meth() 实例方法。
【解决方案3】:

假设你的 Genrics 类实际上是你的 Test 类,它应该相当于这样:

public class Genrics {

    Object lst;
    List list1;
    void meth() throws InstantiationException, IllegalAccessException {
        Object res = lst.getClass().newInstance();
    }

    static void meth(Object t){}
}  
class TestUse{
    public static void main(String[] args) {
        Genrics gint = new Genrics();
        Genrics gstr = new Genrics();
        gint.meth();
        gstr.meth();
}

无论我的假设是对还是错,考虑这一点的方法是所有泛型类型参数都从您的代码中简单地删除并替换为类型参数的最具体绑定(在您的情况下为Object)或什么都没有在适当情况下。在需要的地方引入演员表。

Java Language Specification 中详细说明了类型擦除的工作原理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    相关资源
    最近更新 更多