[英]Java Generics - wildcards
I'm new to Java and have gotten myself into a situation where it's evident that I'm misunderstanding something about how it handles Generics, but reading tutorials and searching stackoverflow hasn't (at least so far) given me clarity beyond that I suspect I'm misusing wildcards. 我是Java的新手,我陷入了一种情况,很明显我对它如何处理泛型有误解,但阅读教程和搜索stackoverflow并没有(至少到目前为止)没有使我更加清楚我滥用通配符。 As a heads up I have a C++ background, so how it deals with templates is probably coloring how I've approached this.
请注意,我具有C ++背景,因此它与模板的处理方式可能会为我的处理方式着色。
Here's the basic structure of my inheritance using representative classes 这是我使用代表类进行继承的基本结构
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
}
}
That seems to all be correct (or at least eclipse isn't complaining), issues seem to arise when I'm attempting to make use of them. 这似乎都是正确的(或者至少是日食没有抱怨),当我尝试使用它们时似乎出现了问题。 My first attempt was:
我的第一次尝试是:
class User{
PacketParser mParser;
User(PacketParser parser){
mParser = parser;
}
void DoSomething(){
Packet packet = mParser.obtainPacket();
// do some stuff with the packet
mParser.parse(packet);
}
}
and led to warnings of Raw types. 并引发了Raw类型的警告。 So I tried...
所以我尝试了...
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);
}
}
But this leads to an error that 但这会导致错误
The method parse(capture#9-of ? extends Packet) in the type PacketParser> is not applicable for the arguments (Packet) 类型为PacketParser>的方法parse(capture#9-of扩展Packet)不适用于参数(Packet)
At this point I've decided that I'm misunderstanding something about how the generics are working, so I've turned to stackoverflow to hopefully point me to where I've gone wrong and maybe point me in the right direction. 在这一点上我已经决定,我误解一些关于泛型是如何工作的,所以我转向StackOverflow的,希望能够指向我,我已经走了错,也许我指出正确的方向。
I have made some changes to your code.It compiling now.Try using this. 我对您的代码进行了一些更改。现在可以编译。尝试使用此代码。
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
}
}
Your User Class. 您的用户类别。
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);
}
}
In your User
code, the compiler doesn't know that the ? extends Packet<? extends PacketHeader>
在您的
User
代码中,编译器不知道? extends Packet<? extends PacketHeader>
? extends Packet<? extends PacketHeader>
? extends Packet<? extends PacketHeader>
on the mParser
field is the same type as the Packet<? extends PacketHeader> packet
mParser
字段上的mParser
? extends Packet<? extends PacketHeader>
与Packet<? extends PacketHeader> packet
类型相同Packet<? extends PacketHeader> packet
Packet<? extends PacketHeader> packet
local variable. Packet<? extends PacketHeader> packet
局部变量。
You need to bind the type of packet that will be used by making User
generic: 您需要通过使
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())
Now the compiler knows that the T
s it sees represent the same type of Packet<?>
, whereas each time it sees ? extends Packet<?>
现在,编译器知道它看到的
T
表示相同类型的Packet<?>
,而每次看到? extends Packet<?>
? extends Packet<?>
could be different subtypes of Packet<?>
. ? extends Packet<?>
可能是不同亚型Packet<?>
。
Edit: An additional note: the " ? extends PacketHeader
" is not needed in the PacketParser
interface declaration, because the Packet
class already limits its T
to PacketHeader
and its subtypes. 编辑:附加说明:
PacketParser
接口声明中不需要“ ? extends PacketHeader
”,因为Packet
类已经将其T
限制为PacketHeader
及其子类型。
// ? is implicitly constrained to "extends PacketHeader" because of
// the way Packet's generic is defined
interface PacketParser<T extends Packet<?>> {
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.