gpt4 book ai didi

java - 从方法返回 Java 有界通用对象

转载 作者:搜寻专家 更新时间:2023-11-01 02:43:10 24 4
gpt4 key购买 nike

我知道 Oracle 教程和类似 How do I make the method return type generic? 的问题但我仍然无法从 Java 方法返回通用对象。

简要示例:我有一个网络 Packet 层次结构和一个 Handler 层次结构,参数化为它们处理的 Packet。最终,我有了一个 Handler注册表,其中包含一个方法,该方法会返回给定数据包的正确处理程序。

我想实现所有这些,理想情况下没有警告来手动抑制。

class Packet {}
class ThisPacket extends Packet {}
class ThatPacket extends Packet {}

interface PacketHandler<P extends Packet> {
boolean handle(P p);
}

class ThisPacketHandler extends PacketHandler<ThisPacket> {
boolean handle(ThisPacket p);
}

class ThatPacketHandler extends PacketHandler<ThatPacket> {
boolean handle(ThatPacket p);
}

我相信这是很正常的,在我的实现中,我在中间有一些进一步的抽象类来塑造我的层次结构,但我认为现在可以忽略它。

关键部分是 i) 注册表:

class HandlersRegistry {
static <<RETURN TYPE>> getHandler(Packet p) {
if (p instanceof ThisPacket) return new ThisPacketHandler();
if (p instanceof ThatPacket) return new ThatPacketHandler();
return null;
}
}

<<RETURN TYPE>> OPTIONS (I tried):
// Raw-type Warning:
A. PacketHandler
// the registry user won't be able to use the handler:
B. PacketHandler<? extends Packet>
// Type mismatch: cannot convert from
C. PacketHandler<Packet>

..和 ii) 和注册表用户:

class HandlerSwitchExample {
public static void main() {
// [...]
<<OBJECT TYPE>> handler = HandlersRegistry.getHandler(somePacket);
handler.handle(somePacket);
}
}

希望这个例子相当清楚。感谢您提供任何有用的建议,甚至是完整的重新设计策略。

最佳答案

您基本上有两个平行的层次结构(PacketPacketHandler),其中一个层次结构中的每个级别都与另一个层次结构中的相同级别相关。下图显示了您的结构(跳过了 ThatHandler)

  Packet ------------> PacketHandler
^ ^
| |
ThisPacket --------> ThisPacketHandler

这些情况通常使用自引用类型参数来解决。此外,使用工厂方法而不是在注册表中创建对象。

这是你的类结构的变化(另外,我想你应该使 Packet 类抽象:

abstract class Packet<T extends Packet<T>> {
/**
* Factory method.
* Override this method in sub-packets to return appropriate handlers
*/
abstract PacketHandler<T> getHandler();
}

那么你的子数据包会是这样的:

class ThisPacket extends Packet<ThisPacket> {
@Override
PacketHandler<ThisPacket> getHandler() {
return new ThisPacketHandlerImpl();
}
}

class ThatPacket extends Packet<ThatPacket> {
@Override
PacketHandler<ThatPacket> getHandler() {
return new ThatPacketHandlerImpl();
}
}

现在,您的PacketHandlers(此处不需要单独的处理程序接口(interface)):

interface PacketHandler<P extends Packet<P>> {
boolean handle(P p);
}

class ThisPacketHandlerImpl implements PacketHandler<ThisPacket> {
@Override
public boolean handle(ThisPacket p) {
return false;
}

}

class ThatPacketHandlerImpl implements PacketHandler<ThatPacket> {
@Override
public boolean handle(ThatPacket p) {
return false;
}
}

最后是注册表:

class HandlersRegistry {
static <P extends Packet<P>> PacketHandler<P> getHandler(P p) {
return p.getHandler();
}
}

然后像这样使用它:

ThisPacket somePacket = new ThisPacket();
PacketHandler<ThisPacket> handler = HandlersRegistry.getHandler(somePacket);
handler.handle(somePacket);

现在,有了上面的结构,你可以继续添加新的数据包,而不需要修改现有的类。只需创建一个 Packet 和相应的 PacketHandler。在新的 Packet 类中覆盖 getHandler() 方法,您就可以使用它了。现在还需要更改注册表类。

关于java - 从方法返回 Java 有界通用对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29119731/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com