Java泛型方法的继承和覆盖规则
我有一个具有泛型方法的抽象类,我想通过用特定类型替换泛型参数来覆盖泛型方法。所以在伪代码中我有以下内容:
public abstract class GetAndParse {
public SomeClass var;
public abstract <T extends AnotherClass> void getAndParse(T... args);
}
public class Implementor extends GetAndParse {
// some field declarations
// some method declarations
@Override
public <SpecificClass> void getAndParse(SpecificClass... args) {
// method body making use of args
}
}
但由于某种原因我不允许这样做?我是否犯了某种语法错误,或者不允许这种继承和覆盖?具体来说,我收到有关 @Override
的错误,因为 eclipse IDE 不断提醒我实现 getAndParse
。
这就是我希望上面的代码如何工作。在我的代码的其他地方,有一个方法需要实现 GetAndParse
的对象实例,这特别意味着它们有一个我可以使用的 getAndParse
方法。当我在该实例上调用 getAndParse
时,编译器会检查我是否以正确的方式使用了 T
的特定实例,特别是 T
应该扩展AnotherClass
并且它应该是SpecificClass
。
I have an abstract class that has a generic method and I want to override the generic method by substituting specific types for the generic parameter. So in pseudo-code I have the following:
public abstract class GetAndParse {
public SomeClass var;
public abstract <T extends AnotherClass> void getAndParse(T... args);
}
public class Implementor extends GetAndParse {
// some field declarations
// some method declarations
@Override
public <SpecificClass> void getAndParse(SpecificClass... args) {
// method body making use of args
}
}
But for some reason I'm not allowed to do this? Am I making some kind of syntax error or is this kind of inheritance and overriding not allowed? Specifically I'm getting an error about @Override
because the eclipse IDE keeps reminding me to implement getAndParse
.
Here's how I want the above code to work. Somewhere else in my code there is a method that expects instances of objects that implement GetAndParse
which specifically means that they have a getAndParse
method that I can use. When I call getAndParse
on that instance the compiler checks to see whether I have used specific instances of T
in the proper way, so in particular T
should extend AnotherClass
and it should be SpecificClass
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我们这里有两种不同的方法,每个方法都有单独的类型参数。
这是一个带有名为 T 的类型参数的方法,并以
AnotherClass
为界,这意味着AnotherClass
的每个子类型都可以作为类型参数。这是一个带有名为
SpecificClass
的类型参数的方法,以Object
为界(意味着每种类型都可以作为类型参数)。你真的想要这个吗?Args
内部使用了类型参数吗?我想问题就在那里。的含义
是,方法的调用者可以决定使用哪种类型参数来调用该方法,只要这是
AnotherClass
的某个子类型。这意味着实际上可以使用AnotherClass
类型的任何对象调用该方法。由于调用者可以决定类型参数,因此您不能在子类中将参数类型缩小为
SpecificClass
- 这不是该方法的实现,而是另一个同名的方法(重载) 。也许您想要这样的东西:
现在
getAndParse
方法实现了父类的方法。What we are having here is two different methods with individual type parameters each.
This is a method with a type parameter named T, and bounded by
AnotherClass
, meaning each subtype ofAnotherClass
is allowed as a type parameter.This is a method with a type parameter named
SpecificClass
, bounded byObject
(meaning each type is allowed as a type parameter). Do you really want this?Is the type parameter used inside
Args
? I think the problem would be there.The meaning of
is that the caller of the method can decide with which type parameter he wants to call the method, as long as this is some subtype of
AnotherClass
. This means that in effect the method can be called with any objects of typeAnotherClass
.Since the caller can decide the type parameter, you can't in a subclass narrow down the parameter type to
SpecificClass
- this would not be an implementation of the method, but another method with same name (overloading).Maybe you want something like this:
Now the
getAndParse
method implements the parent class' method.您之所以会遇到此问题,是因为 Java 泛型中称为“擦除”的概念。
Java使用“擦除”来支持向后兼容性。即没有使用泛型的Java 代码。
擦除程序:
编译器将首先进行类型检查,然后尽可能地删除(擦除)所有类型参数,并在必要时插入 TypeCasting。
例如:
会变成
在类“Implementor.java”中,
代码
会变成
编译器会看到你没有正确实现抽象方法。
抽象方法和实现方法之间存在类型不匹配。这就是您看到错误的原因。
更多详细信息可以在这里找到。
http://today.java.net/pub/a /today/2003/12/02/explorations.html
You are seeing this problem because of the concept called "Erasure" in Java Generics.
Java uses "erasure" to support backward compatibility. i.e Java code which did not use generics.
Erasure Procedure:
The compiler will first do a type checking and then it will remove(erase) all the type parameters as much as possible, and also insert TypeCasting where ever necessary.
example:
will become
In class "Implementor.java",
The code
will become
the compiler will see that you have not implemented the abstract method correctly.
There is a type mismatch between the abstract method and the implemented method. This is why you are seeing the error.
More details can be found here.
http://today.java.net/pub/a/today/2003/12/02/explorations.html
您不能覆盖特定类型T,因为实际上(如果您愿意,在字节码级别)由于类型擦除而只有一种方法
getAndParse
(请参阅其他答案):每种类型的T,都使用相同的方法。
你可以重载它(我认为):
但这与(1)ant的方法没有什么不同,它将不会被通用代码调用:
You cannot override to specific type T because there is in fact (at the bytecode level if you wish) only one method
getAndParse
because of type erasure (see other answer):For every type of T, the same method is used.
You can overload it (I think):
but this will not a different method from (1) ant it will not be called by generic code:
不,这是无效的。如果拥有
GetAndParse
引用的人使用扩展AnotherClass
的不同类来调用它,会发生什么?No, it's not valid. What would happen if someone with a
GetAndParse
reference called it with a different class extendingAnotherClass
?当有人引用类型 GetAndParse 并尝试调用 getAndParse 方法时,这就变得毫无意义了。如果 Cat 和 Dog 扩展 AnotherClass。我应该期望能够使用 Cat 或 Dog 调用 GetAndParse#getAndParse。但实现却试图限制它并使其兼容性降低!
That becomes a nonsense when someone has a reference to type GetAndParse and tries to call the getAndParse method. If Cat and Dog extend AnotherClass. I should expect to be able to call GetAndParse#getAndParse with either a Cat or a Dog. But the implementation has tried to restrict it and make it less compatible!
静态方法无法重写
私有方法无法重写
最终方法无法重写
Static method can't override
Private method can't override
Final method can't override