【问题标题】:Calling ungeneric methods from generic method in java从java中的泛型方法调用非泛型方法
【发布时间】:2013-07-26 18:26:13
【问题描述】:

考虑以下几点:

public class Doer {
   public static void doStuff(A a) {
       System.out.println("a");
   }
   public static void doStuff(B b) {
    System.out.println("b");
   }
}

B 延伸 A

还有一个像这样的通用类:

public class NewClass<T extends A> {
    public void doSomething(T entity) {
        Doer.doStuff(entity);
    }
}

如果我按如下方式调用此方法,它会打印“a”

new NewClass<B>().doSomething(new B());

如何让它打印“b”?

提前致谢

编辑:一个肮脏的解决方案是改变

Doer.doStuff(entity);

if(entity instanceof B){
    Doer.doStuff((B) entity);
}else {
    Doer.doStuff(entity);
}

但我正在寻找一个不使用 instanceof 的解决方案,这样当我创建一个扩展 A 的新类时,我不必向 NewClass 添加额外的 if (C intance of A) ... p>

【问题讨论】:

  • 您作为实体传递的对象。 A 对象或 B 对象 [父/子]。
  • 在 java 中,要调用的方法在编译时而不是运行时解析。这意味着您正在传递A 的某个子类——这是编译器所知道的。 doStuff(A a) 将始终被调用。
  • 我认为您必须检查 doStuff 方法中的类型,该方法采用 A
  • @Boris 有没有办法解决这个问题,而无需执行“if (entity instanceof B) Doer.doStuff((B) entity; else Doer.doStuff(entity); ?
  • 鉴于这种情况,我想我会将 A/B 差异从 Doer 移出并进入 A 和 B 中的重写方法,并且让 Doer 只有一个 DoStuff(A a) 调用,这样Doer 不知道具体情况,只知道 A 的 API。可能不是你需要的,但不知道细节,这就是我要做的。

标签: java generics downcast


【解决方案1】:

请参阅以下问题以获得答案:Java Generic / Type Dispatch QuestionHow does Java method dispatch work with Generics and abstract classes?

基本上,您有以下选择:

  • doStuff定义为A上的抽象方法
  • 尝试访问者模式
  • 如果可能,请使用支持dynamic dispatch 的语言(例如 Xtend)

【讨论】:

    【解决方案2】:

    Java 不会根据参数类型进行动态绑定。调用的实际方法是在编译时确定的。所以在泛型的情况下,会调用以Object为参数类型的方法。

    您可以通过使用 instanceof 检查类型来解决此问题,但处理此问题的纯粹方法是利用多态性并使用 Double Dispatch。但这并不总是一种选择,因为它将调用类和参数类紧密耦合在一起。

    【讨论】:

      【解决方案3】:

      我认为在这种情况下,您必须实际确定实体的类型并进行转换,因为您的函数 doSomething 只是推断该实体从 A 继承。 基本上你可以这样做:

      public void doSomething(T entity) {
          if (entity instanceof B) {
              Doer.doStuff((B) entity);
          }
          else {
              Doer.doStuff(entity);
          }
      }
      

      【讨论】:

        【解决方案4】:

        NewClass 也必须有两个方法,或者你可以这样做:

        public class NewClass<T extends A> {
            public void doSomething(T entity) {
                if(entity instanceof B){
                    Doer.doStuff((B)entity);
                }else if(entity instanceof A){
                    Doer.doStuff((A)entity);
                }
            }
        }
        

        【讨论】:

        • 另外,我认为这不会有帮助。
        • 对不起,我也意识到了这一点,并改变了我的答案。
        • 这确实可行,但我正在寻找一个不使用 instanceof 的解决方案,这样当我有 15 个扩展 A 的类时,我不会得到 15 个 if instanceof else 子句每个人在 Doer 中都有自己的方法
        • 抱歉,如果没有 15 个 instanceof 检查,我看不出有什么办法。祝你好运!
        猜你喜欢
        • 2011-04-23
        • 1970-01-01
        • 1970-01-01
        • 2011-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多