Java 通用问题 : Any better way?

标签 java generics

[更新]:我最初的例子没有反射(reflect)出我的问题。更新了示例,希望现在更好。

Java 泛型和重载不能很好地结合在一起。

public interface Request<E> {
  E getValue();
}

我有一个通用的参数化 Request 接口(interface),如上,我想写一个 DataStore 类来保存请求携带的负载。不同的负载类型保存逻辑不同。

我真正想要的是类似的东西

public interface DataStore {
  void save(Request<E1> r);
  void save(Request<E2> r);
}

但这当然是违法的。

如果我想保持类型安全,DataStore 必须为我想处理的每种类型声明不同的方法,例如

public interface DataStore {
  // here E1 is the actual type I want to handle, not a generic parameter
  public void saveE1(Request<E1> e); 

  public void saveE2(Request<E2> e);
}

或者牺牲类型安全

public class DataStore {
  public void save(Request e) {
    Object value = e.getValue();
    if (value instanceof ReqE1Impl) {
      // do something
    } else if (value instanceof ReqE2Impl) {
      // do something else
    }
  }
}

两种方式都很糟糕!有没有更好的办法?

最佳答案

更好的方法是让对象知道如何保存自己。如果您仍然想使用 DataStore,您可以这样做:

interface YourInterface {
  void save();
}

interface Request<E extends YourInterface> { 
  E getValue(); 
} 

class DataStore<E extends YourInterface> {
  public void save(Request<E> r) {
    r.getValue().save();
  }
}

您只需确保您的对象然后每个都实现该接口(interface) 和中提琴,泛型和多态性可以很好地相互配合。

注意:您的(修改后的)问题的编写方式,您没有使用多态性。您正在使用重载。方法重载在编译时决定,而方法多态性在运行时决定。这就是您遇到这些困难的部分原因。

如果你真的不想要上面那种由对象完成所有 self 保存工作的设计,那么也许你可以做这样的事情(作为一个非常弱的例子):

interface YourInterface {
  String serialize();
}

interface Request<E extends YourInterface> { 
  E getValue(); 
} 

class DataStore<E extends YourInterface> {
  public void save(Request<E> r) {
    String value = r.getValue().serialize();
    // Now do something with value to save to a datastore
  }
}

上面是一个薄弱的例子,但主要思想是对象知道如何执行对象之间不同的序列化部分,然后 DataStore 可以执行所有对象共有的工作。

是的,您是对的(用错了术语)——泛型在重载方面表现不佳。但是它们确实可以很好地处理多态性。无论如何,多态性通常是比重载更好的工具。

关于Java 通用问题 : Any better way?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/800731/

相关文章:

c# - 如何缩短 List<List<KeyValuePair<string, string>>>?

java - 使用 Java Applet 在浏览器内滚动到顶部

java - List<A> 不能发送到方法( List<superclass-of-A> )——为什么不呢?

Java、泛型、合并、比较

java - 根据用户输入打印不同的句子

java - Guava:将 Multimap 转换为通用父类(super class)型是否有效?

java - Mockito 匹配器 : matching a Class type in parameter list

java - 空字段验证在 Struts 2 中不起作用

java - 安卓短信管理器

java - 使用servlet的xml解析问题