实现通用接口的抽象类上的Loosing List类型

时间:2013-03-18 10:08:42

标签: java generics type-erasure

我在理解以下情况时遇到了一些麻烦。 我有一个“generified”接口,由一个抽象类和一个扩展抽象类的具体类实现。

问题是返回参数化列表的抽象类中的所有方法都丢失了它们的类型,因此我收到编译错误,告诉我它无法从对象转换为原始的List类型。

有人能提供一些见解吗?

最后我想要的是在抽象类上有一个getId和setId方法,返回类型为java.lang.object<T extends Object>,并且具体的类实现了它们的返回类型。想。

以下是我的不同对象的代码:

通用界面

public interface MyInterface<T>{

   public T getId();
   public void setId(T id);

}

实现接口的抽象类

public abstract class MyAbstractClass<T> implements MyInterface<T>{

  private List<String> texts;
  private List<Integer> notes;

   public List<String> getTexts(){
     return texts;
   }

   public List<Integer> getNotes(){
     return notes;
   }
}

实现抽象类

的Concrete类
public class MyConcreteClass implements MyAbstractClass<Integer>{

    private Integer id;

    public Integer getId(){
       return this.id;
    }


    public void setId(Integer id){
          this.id = id;
    } 

}

其他一些课程:

 public class SomeOtherClass{

   public void process(List<T extends MyAbstractClass> myClassList){

  // Compilation error -> 
  // Type mismatch: cannot convert from element type Object to String  
       for(MyAbstractClass myObj : myClassList){

            System.out.println("object Id : " + myObj.getId());

              // Compilation error -> 
              // Type mismatch: cannot convert from element type Object to String  
             for(String txt : myObj.getTexts()){


             }
       }
   }

}

2 个答案:

答案 0 :(得分:4)

当您使用泛型类型MyAbstractClass<T>作为原始类型(MyAbstractClass)时,其成员声明中的所有与泛型相关的内容都将被禁用(即List<String>变为List )。

因此,您需要将方法的参数声明为参数化类型。如果您不关心实际的类型参数,请使用通配符:

public void process(MyAbstractClass<?> myClass) { ... }

答案 1 :(得分:1)

我认为你需要另一个界面。请参阅此处MyAbstractClass实现两个接口MyInterface<T>, MyOtherInterface

  public static interface MyInterface<T> {
    public T getId();

    public void setId(T id);
  }

  public static interface MyOtherInterface {
    public List<String> getTexts();

    public List<Integer> getNotes();
  }

  public abstract class MyAbstractClass<T> implements MyInterface<T>, MyOtherInterface {
    private List<String> texts;
    private List<Integer> notes;

    public List<String> getTexts() {
      return texts;
    }

    public List<Integer> getNotes() {
      return notes;
    }
  }

  public static class MyConcreteClass extends MyAbstractClass<Integer> {
    private Integer id;

    public Integer getId() {
      return this.id;
    }

    public void setId(Integer id) {
      this.id = id;
    }
  }

  public class SomeOtherClass {
    public void process(MyOtherInterface myClass) {

      // NO Compilation error
      for (String str : myClass.getTexts()) {
        // some processing
      }
    }
  }