简体   繁体   English

Java泛型-遇到棘手的情况

[英]Java generics - having trouble with a tricky situation

I've beat my head against the wall on this one for several hours now, and I've distilled it down to a tiny bit of code. 现在,我已经把头撞在墙上的墙上好几个小时了,我已经将其精炼为一小段代码。 Can you see where the error is? 您能看到错误在哪里吗?

public class Experiment {
   class BaseMessage<Messageable> {
      Messageable once;

      BaseMessage(Messageable x) {
         once = x;
      }
   }

   class BaseEntity {
      boolean handleMessage(BaseMessage<BaseEntity> theMessage) {
         return false;
      }

   }

   class StateMachine<Thing> {
      public boolean handleMessage(BaseMessage<Thing> msg) {
         return true;
      }

   }

   class VehicleEntity extends BaseEntity {
      public StateMachine<VehicleEntity> state;

      @Override
      boolean handleMessage(BaseMessage<VehicleEntity> theMessage) {
         return state.handleMessage(theMessage);
      }
   }
}

I get a compiler error on this line: 我在这一行收到编译器错误:

boolean handleMessage(BaseMessage<VehicleEntity> theMessage) {

The error is: "The method handleMessage(Experiment.BaseMessage<Experiment.VehicleEntity>) of type Experiment.VehicleEntity must override or implement a super type method" 错误是: "The method handleMessage(Experiment.BaseMessage<Experiment.VehicleEntity>) of type Experiment.VehicleEntity must override or implement a super type method"

Note that this is a sample subset of my real code to reduce it to its minimum so the code doesn't do anything sensible. 请注意,这是我的真实代码的示例子集,可将其减少到最低限度,因此代码不会做任何明智的事情。 Wow, if you could figure this out I would be super grateful! 哇,如果您能解决这个问题,我将不胜感激!

As stated by Miserable Variable, in VehicleEntity you have handleMessage(BaseMessage<VehicleEntity> theMessage) not handleMessage(BaseMessage<BaseEntity> theMessage) and the compiler expects the latter in your original code. 如Miserable Variable所述,在VehicleEntity您有handleMessage(BaseMessage<VehicleEntity> theMessage)而不是handleMessage(BaseMessage<BaseEntity> theMessage) ,并且编译器期望在原始代码中使用后者。

The main alternative is for BaseEntity to take a "self" type argument as follows: 主要替代方法是让BaseEntity接受“ self”类型的参数,如下所示:

class BaseEntity<T extends BaseEntity<T>> {
  boolean handleMessage(BaseMessage<T> message) {
    ...
  }
}
class VehicleEntity extends BaseEntity<VehicleEntity> {
  boolean handleMessage(BaseMessage<VehicleEntity> message) {
    ...
  }
}

BaseMessage<VehicleEntity> is not a subtype of BaseMessage<BaseEntity> . BaseMessage<VehicleEntity>不是BaseMessage<BaseEntity>的子类型。 Try this 尝试这个

abstract class BaseEntity {
    abstract <B extends BaseEntity> boolean handleMessage(BaseMessage<B> theMessage) {
        return false;
    }
}

You would like for VehicleEntity to have a handleMessage method that will accept only a BaseMessage<VehicleEntity> . 您希望VehicleEntity具有handleMessage方法,该方法仅接受BaseMessage<VehicleEntity>

I believe this is only possible in Java, at least it cannot be checked statically. 我相信这仅在Java中是可能的,至少不能静态检查。 But you may want to look at Curiously recurring template pattern to see if you can make it work for you. 但是,您可能需要查看“ 好奇地重复使用”模板模式,以查看是否可以使其适合您。

Try adding generics to the class itself 尝试将泛型添加到类本身

   class BaseEntity<T> {
      boolean handleMessage(BaseMessage<T> theMessage) {
         return false;
      }

   }

And

   class VehicleEntity extends BaseEntity<VehicleEntity> {
      public StateMachine<VehicleEntity> state;

      @Override
      boolean handleMessage(BaseMessage<VehicleEntity> theMessage) {
         return state.handleMessage(theMessage);
      }
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM