返回不同类型的方法?

时间:2015-09-03 09:34:59

标签: java collections iterator

我正在写一个方法。

这是层次结构树:

IProtocoll
|
|--ProtocolImpl1
|
|--ProtocolImpl2
|
|--ProtocolImpl3

方法本身如下:

public static List<IProtocol> getProtocolsByType(String type, Transaction trx) {
    Iterator<IProtocol> protocols = trx.getProtocols();
    List<IProtocol> protocolsList = new ArrayList<IProtocol>();
    while (protocols.hasNext()) {
        if (StringHeper.isEqual(protocolls.next().getProtocolType(), type) {
            protocolsList.add(protocolls.next());
        }
    }
    return protocolsList
}

用法示例。

List<IProtocol> list = ProtocolHelper.getrProtocolsByType("PROTOCOL1", trx)

for (IProtocol protocol : list) {
    ProtocolHelper.createProtocolType1((ProtocolImpl1) protocol)
}

现在 - 正如在类型层次结构中看到的那样,这种方法可以返回3种可能性。

String type定义了应返回的协议类型。 trx.getProtocols()将返回包含所有3种类型协议的迭代器。

有没有办法以某种方式统一这个方法,它会返回这3种类型中的一种,而不会在以后使用该方法时使用不必要的转换?

5 个答案:

答案 0 :(得分:6)

您可以尝试以下方法:

public static <T extends IProtocol> List<T> getProtocolsByType(Class<T> typeClass, Transaction trx) {    
  Iterator<IProtocol> protocols = trx.getProtocols();
  List<T> protocolsList = new ArrayList<T>();
  while( protocols.hasNext() ) {
     //call next() only once
     IProtocol p = protocols.next();

     //Check if p is an instance of typeClass or a subtype
     if ( typeClass.isAssignableFrom( p.getClass() ) {
        protocolsList.add( (T)p );
     }
   }
   return protocolsList;
}

List<ProtocolImpl1> list = ProtocolHelper.getrProtocolsByType( ProtocolImpl1.class, trx)

因此,不是将类型作为字符串传递,而是传递您想要获得的实现类。

广告(T)p是必要的,但由于您检查p类型T或子类型是否安全。

答案 1 :(得分:2)

泛型是救世主。使用这样的东西:

public static <T extends IProtocol> List<IProtocol> getProtocolsByType(Class<T> clazz, Transaction transaction) {    
  //do logic here
}

答案 2 :(得分:1)

这是一个可能的解决方案:

public <I extends IProtocol> List<I> getProtocols(Class<I> protocolClass) {
    Iterator<IProtocol> protocols = trx.getProtocols();
    List<I> protocolsList = new ArrayList<I>();
    while (protocols.hasNext()) {
      if (protocols.next().getClass().equals(protocolClass)) {
          protocolsList.add((I) protocols.next());
      }
    }
    return protocolsList;

}

不要将类型指定为String,而是将其指定为类。使用上述签名,您无需投射。

唯一的问题是对我的强制转换导致警告,但由于我们已经检查了类类型,我们知道它会投好。

答案 3 :(得分:0)

您可以像这样使用它:

List<ProtocolImpl1> list = (List<ProtocolImpl1>) ProtocolHelper.getProtocolsByType("PROTOCOL1", trx)

for (ProtocolImpl1 protocol : list) {
    ProtocolHelper.createProtocolType1(protocol)
}

如果您还想避免该演员表,我根据您当前的代码看到的唯一方法是在ProtocolHelper中创建单独的方法:

List<ProtocolImpl1> getAllProtocolsOfType1(trx);
List<ProtocolImpl2> getAllProtocolsOfType2(trx);
List<ProtocolImpl3> getAllProtocolsOfType3(trx);

但是,如果协议数量增加,那当然不是那么可扩展。

答案 4 :(得分:0)

尝试使用java泛型。 public static <T extends IProtocol> List<T> getProtocolsByType 类型T可以是扩展IProtocol的任何类型。 看一下关于它们的oracle教程 - &gt; https://docs.oracle.com/javase/tutorial/java/generics/ 他们会解决你的问题。