Я новичок в Java и попал в ситуацию, когда очевидно, что я что-то неправильно понимаю в том, как он обрабатывает Generics, но чтение руководств и поиск в 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);
}
}
и приводило к предупреждениям типов Raw. Итак, я попытался...
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);
}
}
Но это приводит к ошибке, которая
Метод parse(capture#9-of ? extends Packet) в типе PacketParser> неприменим для аргументов (Packet)
На данный момент я решил, что я неправильно понимаю что-то о том, как работают дженерики, поэтому я обратился к stackoverflow, чтобы, надеюсь, указать мне, где я ошибся, и, возможно, указать мне в правильное направление.