首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中的逆变类型参数?

Java中的逆变类型参数?
EN

Stack Overflow用户
提问于 2014-09-02 20:07:05
回答 1查看 84关注 0票数 0

我正在考虑将这个C#库移植到Java和Android上。

https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/tree/master/SignalR.EventAggregatorProxy.Client.DotNet

我想移植这个接口

代码语言:javascript
复制
public interface IHandle<in T> where T : class
{
    void Handle(T message);
}

它需要处理矛盾,这样它才能处理IHandle<ISomeIntefaceOrBaseClass>等消息

代码语言:javascript
复制
subscribers
   .OfType<IHandle<T>>();

对于Java泛型,这是可能的吗?还是有一种更“Java方式”的方式来实现这一点?

EN

回答 1

Stack Overflow用户

发布于 2014-09-02 20:23:18

我假设使用subscribers.OfType<IHandle<T>>();时,您希望获取所有类型为IHandle<T>的订阅者,其中T是消息的类型,对吗?

在Java中,您必须对代码进行一些更改,因为由于类型擦除,您不能提供这样类型。

假设每个类型/类都有一个句柄,您可以这样做:

代码语言:javascript
复制
interface IHandle<T> {
   Class<T> getMessageType(); //needed to query the handle for the supported class
   void handle( T message );
}

要创建该接口的实现,您有以下几种选择:

为每个类创建一个实现:

代码语言:javascript
复制
class SpecialMessageHandle implements IHandle<SpecialMessage> {
  public Class<SpecialMessage> getMessageType() { return SpecialMessage.class; }

  public handle( SpecialMessage message ) { ... }
}

或者将类作为参数传递:

代码语言:javascript
复制
class Handle<T> implements IHandle<T> {
  Class<T> messageClass;

  public Handle( Class<T> msgClass ) { messageClass = msgClass; }

  public Class<T> getMessageType() { return messageClass; }

  public handle( T message ) { ... }
}

然后,您可能有一个map消息类来处理类和订阅者的处理类(例如,Guava Multimap):

代码语言:javascript
复制
Map<Class<?>, IHandle<?>> handles = ...;
Multimap<IHandle<?>, Subscriber> subscribers = ...;

请注意,我在这里使用Class<?>是因为我不知道这些类是否有公共的超类或接口。如果你有一个通用的超类或者接口X,那么你应该使用Class<? extends X>

另外,请注意,我使用IHandle<?>是因为在Java语言中,您不能在支持不同键的同时定义键和值需要使用相同泛型类型的映射,也就是说,您不能在每个键都是不同的T的情况下执行Map<Class<T>, IHandle<T>>,而只允许一个适合键的值。

添加句柄如下所示:

代码语言:javascript
复制
handles.put( handle.getMessageType(), handle );

然后,使用消息查询该映射的工作方式如下:

代码语言:javascript
复制
IHandle<?> handle = handles.get( message.getClass() ); 
Collection<Subscriber> handleSubscribers = subscribers.get( handle  );

请注意,如果您还想获得超类的订阅者(例如,如果是SpecialMessage extends Message,并且您还想获得那些订阅了Message的订阅者),那么您需要在类层次结构中向上移动。

下面是你在更上一层楼要做的事情:

代码语言:javascript
复制
handles.get( message.getClass().getSuperclass() );
for( Class<?> interface : message.getClass().getInterfaces() ) {
  handles.get( message );
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25623049

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档