代码之家  ›  专栏  ›  技术社区  ›  phreed

设计Java通用层次结构以避免模板类冲突

  •  0
  • phreed  · 技术社区  · 6 年前

    考虑以下rawtype形式的java泛型类层次结构。

    class A ...
    class B extends A ...
    class C extends A ...
    

    使用类a中的方法,并在B和C中重写。

    String foo() ...
    String bar(A a) ...
    

    我们可以成功地拨打以下电话。

    String r = (new B()).foo();
    String r = (new B()).bar(new C());
    

    这里的真正目标是在容器中保存 把它们都处理掉,不管我们是哪种人。

    A fred;
    List as = new LinkedList();
    for (A a : as) ... fred.bar(a); ...
    

    类B和类C的对象可以构造并毫无问题地传递给foo。 现在我们介绍泛型。

    class A<T,U,V> ...
    class B<T> extends A<T,Void,Object> ...
    class C<N> extends A<String,Void,Object> ...
    

    使用类a中的方法,并在B和C中重写。

    T foo() ...
    

    然后我们打以下合理的电话。

    String r = (new A<String,Void,Object>()).foo();
    String r = (new B<String>()).foo();
    String r = (new C<Integer>()).foo();
    
    String r = (new B<String>()).foo();
    String r = (new B<String>()).bar(new C<Integer>());
    

    这里的真正目标是在容器中保存 把它们都处理掉,不管我们是哪种人。

    A<String,String,Integer> fred;
    List<A<String,String,Integer>> as = new LinkedList<>();
    for (A a : as) ... fred.bar(a); ...
    

    这些决定使得无法将B和C类型的对象加载到“as”列表中, 由于泛型模板中的类型冲突。

    请注意,这是一个现有的软件,我正在尝试清除警告。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Radiodef    6 年前

    如果你只关心 foo() ,则可以使用此:

    List<A<String, ?, ?>> as = ...;
    

    那会让你储存 A 或任何 一个 的类型参数 T String ,但有任何东西 U V . 所以:

    as.add(new A<String, String, Integer>()); // fine
    as.add(new B<String>()); // fine
    as.add(new C<Integer>()); // fine
    
    as.add(new A<Double, String, Integer>()); // won't compile
    

    但是,您将无法调用 一个 具有类型参数的 U型 是的。如果这是个问题,那么你似乎必须重新设计。

    可能还会看到: