1

我不太习惯泛型,所以我在这里有点困惑我应该如何解决这个问题。我编写了一个尝试在运行时调用不同方法的方法。但是我得到了一个ClassCastException虽然代码在语法上看起来是正确的。

我有以下类(为简洁起见,省略了一些 getter 和 setter):

public interface Transporte extends Serializable {
  private int id;
  private String name;
  public abstract int getId() { return this.id; }
  public abstract String getName() { return this.name; }
}
public class Barco implements Transporte { /* ... */ }
public class Estacao implements Transporte { /* ... */ }
public class Paragem implements Transporte { /* ... */ }

public class Entidade extends Serializable {
  private List<Barco> barcos;
  private List<Estacao> estacoes;
  private List<Paragem> paragens;
  public List<Barco> getBarcos() { return this.barcos; }
  public List<Estacao> getEstacoes() { return this.estacoes; }
  public List<Paragem> getParagens() { return this.paragens; }
}

我正在尝试实施但遇到困难的方法:

public <T extends Transporte> List<T> intersectTransportes(Entidade entidade, List<T> transportes) {
  if(entidade==null || transportes==null) return null;

  T typeOfTransport = (T) new Object(); /* <--- HERE'S THE PROBLEM (?) */
  List<T> result = new ArrayList<T>();
  List<Integer> ids = null;

  if(typeOfTransport instanceof Barco) ids = entidade.getIdBarcos(); else
  if(typeOfTransport instanceof Estacao) ids = entidade.getIdEstacoes(); // else ...

  // now do the work
  for(Transporte t : transportes) {
    for(Integer id : ids) {
      if(t.getId()==id) result.add((T) t);
    }
  }

  return result;
}

请注意,我正在使用<T extends Transporte>而不是<T implements Transporte>我期望 Java 允许的那样。但是后一种语法是无效的,所以我必须implements改用......

正在调用该方法,如下所示:

List<Estacao> allStations;
List<Estacao> myStations = intersectTransportes(entidade, allStations);

我在这里尝试做的是在调用该方法时识别运行时使用的实际类型。在这种情况下,insersectTransportes应该能够识别我正在使用的特定实现对象ListTransporte

我怀疑我应该使用其他东西

T typeOfTransporte = (T) new Object(); 

因为显然这是产生运行时异常的那一行。但是,我不太确定如何解决这个问题。对解决方案(或解决此问题的特定参考书目)的任何指示表示赞赏。

4

5 回答 5

2

问题是:

  • a)你不能new你的泛型类型 - 它在运行时被删除
  • b)对象不扩展Transporte,因此不能转换为T
于 2011-06-07T09:43:14.373 回答
1

您需要将类传递给您的方法:

public <T extends Transporte> List<T> intersectTransportes(Entidade entidade, List<T> transportes, Class<T> clazz) {

...
T typeOfTransporte = clazz.newInstance();
于 2011-06-07T09:44:16.197 回答
1
T typeOfTransport = (T) new Object(); /* <--- HERE'S THE PROBLEM (?) */

问题相当明显,对象不是“传输类型”(不实现或扩展传输接口)。

在这个例子中你会得到同样的错误: String myStr = (String) new Object();

T typeOfTransport = (T) new Barco(); //new Barco() or anything that implements Transport interface

您必须在那里实例化一个特定的类,但不能实例化任何类,如 Object。该类必须实现 Transport 接口。

于 2011-06-07T09:55:05.557 回答
0

当然 (T) new Object() 有问题。当您调用 new Object() 时,它会创建类 Object 的实例,就是这样。你不能把它转换成有用的东西。

尝试像这样编写您的方法:

public <T extends Transporte> List<T> intersectTransportes(Entidade entidade, List<T> transportes, Class<T> clasz)

并使用反射。

于 2011-06-07T09:44:34.973 回答
0

Transporte您应该通过一个方法(可能使用开关)传入一个处理创建新的工厂createNew(Class<? extends T> transporteClass)

您还应该考虑使用 commons-collections 或 guava 库,它们具有您正在寻找的交集方法,从而省去了编写此代码的麻烦。

于 2011-06-07T09:49:29.097 回答