我正在考虑将这个C#库移植到Java和Android上。
我想移植这个接口
public interface IHandle<in T> where T : class
{
void Handle(T message);
}它需要处理矛盾,这样它才能处理IHandle<ISomeIntefaceOrBaseClass>等消息
subscribers
.OfType<IHandle<T>>();对于Java泛型,这是可能的吗?还是有一种更“Java方式”的方式来实现这一点?
发布于 2014-09-02 20:23:18
我假设使用subscribers.OfType<IHandle<T>>();时,您希望获取所有类型为IHandle<T>的订阅者,其中T是消息的类型,对吗?
在Java中,您必须对代码进行一些更改,因为由于类型擦除,您不能提供这样类型。
假设每个类型/类都有一个句柄,您可以这样做:
interface IHandle<T> {
Class<T> getMessageType(); //needed to query the handle for the supported class
void handle( T message );
}要创建该接口的实现,您有以下几种选择:
为每个类创建一个实现:
class SpecialMessageHandle implements IHandle<SpecialMessage> {
public Class<SpecialMessage> getMessageType() { return SpecialMessage.class; }
public handle( SpecialMessage message ) { ... }
}或者将类作为参数传递:
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):
Map<Class<?>, IHandle<?>> handles = ...;
Multimap<IHandle<?>, Subscriber> subscribers = ...;请注意,我在这里使用Class<?>是因为我不知道这些类是否有公共的超类或接口。如果你有一个通用的超类或者接口X,那么你应该使用Class<? extends X>。
另外,请注意,我使用IHandle<?>是因为在Java语言中,您不能在支持不同键的同时定义键和值需要使用相同泛型类型的映射,也就是说,您不能在每个键都是不同的T的情况下执行Map<Class<T>, IHandle<T>>,而只允许一个适合键的值。
添加句柄如下所示:
handles.put( handle.getMessageType(), handle );然后,使用消息查询该映射的工作方式如下:
IHandle<?> handle = handles.get( message.getClass() );
Collection<Subscriber> handleSubscribers = subscribers.get( handle );请注意,如果您还想获得超类的订阅者(例如,如果是SpecialMessage extends Message,并且您还想获得那些订阅了Message的订阅者),那么您需要在类层次结构中向上移动。
下面是你在更上一层楼要做的事情:
handles.get( message.getClass().getSuperclass() );
for( Class<?> interface : message.getClass().getInterfaces() ) {
handles.get( message );
}https://stackoverflow.com/questions/25623049
复制相似问题