私は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
}
}
それはすべて正しいようです(または少なくとも日食は不平を言っていません)、私がそれらを利用しようとすると問題が発生するようです。私の最初の試みは:
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);
}
}
しかし、これはエラーにつながります
タイプPacketParser>のメソッドparse(capture#9-of?extends Packet)は、引数(Packet)には適用できません。
この時点で、ジェネリックがどのように機能しているかについて何か誤解していると判断したので、stackoverflowを使用して、間違っている場所を示し、正しい方向に向けることができればと思います。