1

我是 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,希望能指出我出错的地方,并可能为我指明正确的方向。

4

2 回答 2

0

我对您的代码进行了一些更改。现在正在编译。尝试使用它。

   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> {
        public TypeOfPacket obtainPacket() {
            return TypeOfPacket().obtain();
        }

        private TypeOfPacket TypeOfPacket() {
            // TODO Auto-generated method stub
            return null;
        }

        public void parse(TypeOfPacket packet) {
            // code that relies on TypeOfPacket specific functions
        }
    }

您的用户类别。

class User{
    private PacketParser mParser;

    User(PacketParser parser) {
        mParser = parser;
    }

    void DoSomething() {
        Packet packet = mParser.obtainPacket();
        // do some stuff with the packet
        mParser.parse(packet);
    }
}
于 2012-06-19T20:45:29.013 回答
0

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

User您需要通过使泛型绑定将使用的数据包类型:

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,因为Packet该类已经将其限制TPacketHeader及其子类型。

// ? is implicitly constrained to "extends PacketHeader" because of
// the way Packet's generic is defined
interface PacketParser<T extends Packet<?>> {
于 2012-06-19T20:47:06.533 回答