gpt4 book ai didi

Java 泛型 - 通配符

转载 作者:行者123 更新时间:2023-12-01 05:16:38 29 4
gpt4 key购买 nike

我是 Java 新手,并且已经陷入这样一种情况,很明显我误解了它如何处理泛型,但是阅读教程和搜索 stackoverflow 并没有(至少到目前为止)让我清楚我怀疑我滥用了通配符。需要注意的是,我有 C++ 背景,因此它如何处理模板可能会影响我的处理方式。

这是我使用代表性类继承的基本结构

abstract class PacketHeader{
// some stuff
}

class TypeOfPacketHeader extends PacketHeader{
// extended stuff
}

abstract class Packet<T extends PacketHeader>{
T mHeader;
// some methods treating T as a type of PacketHeader
// some abstract methods
}

class TypeOfPacket extends Packet<TypeOfPacketHeader>{
static TypeOfPacket obtain {
return new TypeOfPacket();
}
// overriden abstract functions that call specific TypeOfPacketHeader methods on mHeader
}

interface PacketParser<T extends Packet<? extends PacketHeader>>{
T obtainPacket();
void parse(T packet);
}

class ImplementedPacketParser implements PacketParser<TypeOfPacket>{
TypeOfPacket obtainPacket(){
return TypeOfPacket.obtain();
}
void parse(TypeOfPacket packet){
// code that relies on TypeOfPacket specific functions
}
}

这似乎都是正确的(或者至少 Eclipse 没有提示),当我尝试使用它们时似乎出现了问题。我的第一次尝试是:

class User{
PacketParser mParser;

User(PacketParser parser){
mParser = parser;
}

void DoSomething(){
Packet packet = mParser.obtainPacket();
// do some stuff with the packet
mParser.parse(packet);
}
}

并导致了原始类型的警告。所以我尝试...

class User{
PacketParser<? extends Packet<? extends PacketHeader>> mParser;

User(PacketParser<? extends Packet<? extends PacketHeader>> parser){
mParser = parser;
}

void DoSomething(){
Packet<? extends PacketHeader> packet = parser.obtainPacket();
// do some stuff with the packet
mParser.parse(packet);
}
}

但这会导致一个错误

PacketParser> 类型中的方法 parse(capture#9-of ? extends Packet) 不适用于参数 (Packet)

在这一点上,我认为我对泛型的工作方式有一些误解,所以我转向 stackoverflow,希望能指出我出错的地方,也许为我指明正确的方向。

最佳答案

在您的 User 中代码,编译器不知道 ? extends Packet<? extends PacketHeader>关于mParser字段与 Packet<? extends PacketHeader> packet 的类型相同局部变量。

您需要通过创建User来绑定(bind)将使用的数据包类型。通用:

class User<T extends Packet<?>> {
PacketParser<T> mParser;

User(PacketParser<T> parser){
mParser = parser;
}

void DoSomething(){
T packet = parser.obtainPacket();
// do some stuff with the packet
mParser.parse(packet);
}
}

// and then when instantiating your User, specify the packet type:
new User<TypeOfPacket>(new ImplementedPacketParser())

现在编译器知道 T它看到的 s 代表相同类型的 Packet<?> ,而每次看到 ? extends Packet<?>可能是 Packet<?> 的不同子类型.

编辑:附加说明:? extends PacketHeader 中不需要“PacketParser ”接口(interface)声明,因为 Packet类已经限制了它的 TPacketHeader及其亚型。

// ? is implicitly constrained to "extends PacketHeader" because of
// the way Packet's generic is defined
interface PacketParser<T extends Packet<?>> {

关于Java 泛型 - 通配符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11108982/

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