【问题标题】:Generic method that accepts two types of List接受两种类型 List 的通用方法
【发布时间】:2013-06-20 22:02:26
【问题描述】:

我想写一个可以接受两种相似类型的函数。但不一样。

MyClassA {
  abc()
  a2b()
}

MyClassB {
   abc()
   a3b()
}

这两种方法中的一种方法是相同的。该函数应该接受这两种类型中的任何一种,我想在列表中的对象上调用 abc()。

这似乎没有帮助:

    private <T> Set<MyclassX> createObject(List<T> classes) {

          Set<MyclassX> x;

          if ( T instanceof MyClassA)  {
               for ( MyClassA a : classes ) {
                    if (a.abc().equals("somethig")) {
                         x.add( t.abc());
                     }   
                }   
           }
           return x;
     }

我什至不需要检查instanceof。我只需要遍历列表并比较值。如果匹配,则调用方法abc()

【问题讨论】:

  • 编译和运行代码时会发生什么?你有任何错误吗?
  • 另外请出示is t的声明?
  • 你的两个类中方法的返回类型是什么。
  • 其实我正在尝试写两种方法。但是eclipse显示两者实际上是相同的。是的,这两种方法都接受不同类型的列表。但是列出来。所以它不允许。
  • 两者都返回相同的 MyClassX

标签: java list generics methods


【解决方案1】:

只需创建一个通用接口,让 MyClassA 和 MyClassB 实现它:

interface MyClass {
    void abc();
}

【讨论】:

  • Hmmmm.. 这两个是@Entity 的。所以我不想那样做。
  • 或者做一个抽象超类,用@Entity就可以了,看看mapped-superclass
  • 请编辑您的问题以显示abstract 类解决方案。
  • 如果你不能修改类,那么泛型不适合你的情况,因为你没有任何共同点。要执行您建议的操作,您只需使用类 Object 然后检查 instanceof,就像您已经在做的那样。但是如果你的对象只是实体,为什么你有一些逻辑呢?或者abc 只是一个吸气剂?如果是这种情况,我会采用@KevinRave 提出的解决方案。
  • @nachokk 这只是一个例子。 关注主要问题。
【解决方案2】:

我建议你像这样使用abstract super class

abstract SuperClass{
  abc();
  abstract ab(); // Only if the other methods share signatures
}

MyClassA extends SuperClass {
  ab();
}

MyClassB extends SuperClass{
  ab();
}

private <T> Set<? extends SuperClass> createObject(List<T> classes) {
   ...
}

如果您只想遍历包含MyClassAMyClassB 实例的集合,请在这些实例上调用abc() 方法。 这可以很好地与 JPA 一起使用,因为有一个名为 MappedSuperclass 的注释。

通过这种方式,您可以以符合您的要求并且可以与泛型一起使用的方式从后代类中分解相同的逻辑。这是how to use的Hibernate示例

【讨论】:

    【解决方案3】:

    使用泛型,您可以这样做:

    private <T> Set<MyclassX> createObject(List<T> classes) {
        Set<MyclassX> x;
        for ( T a : classes ) {
            if (a.abc().equals("somethig")) {
                x.add( t.abc());
            }
        }
    }
    return x;
    }
    

    假设t.abc() 返回MyclassX。 (我的意思是字面意思,我不是假设X 代表其他东西。)

    【讨论】:

    • 呃,不……你不能。因为T 周围没有限定符(意味着它实际上是&lt;T extends Object&gt;)表示它有一个方法abc(),而Object 肯定没有那个方法。
    • gah...我经常将 Java 泛型与 C++ 模板混为一谈;-(
    • 如果不使用从抽象基础派生的接口或类,您必须遍历 List 将每个事物作为 T 实例(或者实际上,只是作为对象)并检查它是否是 @ 987654329@ 东西然后投它。这确实指向糟糕的设计。
    • @BrianRoach 你能用你的解决方案写一个答案吗?
    【解决方案4】:

    类型信息可以作为参数传入

    <T> void method(Class<T> clazz, List<T> list)
    {             
        if(clazz==MyClassA.class)
        {
            @SuppressWarnings("unchecked)
            List<MyClassA> listA = (List<MyClassA>)list;
            ....
        }
        else if...
    

    更好的解决方案可能是在传递之前将List&lt;MyClassX&gt; 转换为List&lt;Abc&gt;

    interface ABC
        abc()
    
    void method(List<Abc> list)
    

    在 java8 中转换可能会很容易

    List<MyClassA> list1 = ...
    method( list1.map( e->e.abc() ) );
    

    【讨论】:

      猜你喜欢
      • 2016-09-23
      • 2012-06-02
      • 2016-01-25
      • 1970-01-01
      • 2016-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-12
      相关资源
      最近更新 更多