Java 添加参数后,使用泛型返回类型重写方法失败
我想知道为什么这是一个有效的覆盖:Java 添加参数后,使用泛型返回类型重写方法失败,java,generics,overriding,Java,Generics,Overriding,我想知道为什么这是一个有效的覆盖: public abstract class A { public abstract <X> Supplier<X> getSupplier(); public static class B extends A { @Override public Supplier<String> getSupplier() { return String::new
public abstract class A {
public abstract <X> Supplier<X> getSupplier();
public static class B extends A {
@Override
public Supplier<String> getSupplier() {
return String::new;
}
}
}
根据编译器输出,两个示例中的方法签名不同(使用
-Xlint:unchecked
选项编译代码以确认):
删除m2的签名:
将m1参数从Collection
更改为原始Collection
可以消除错误,在这种情况下,m1将成为m2的子符号
结论
第一个代码段(有效覆盖):父类和子类中的方法签名最初是不同的。但是,在对父方法应用擦除之后,签名变得相同
第二个代码段(无效重写):方法签名最初是不同的,并且在对父方法应用擦除后仍然是不同的。添加参数后,它就不再是重写,成为重载
泛型与此无关。我得到了
a.B.getSupplier()
@JohannesKuhn警告的未检查转换警告,但不是错误。因此B.getSupplier
覆盖A.getSupplier
。在getSuppliers
的情况下,我们将得到一个编译器错误。因此B.getSuppliers
不会覆盖A.getSuppliers
。为什么?似乎还要求添加的参数是泛型类型才能获得错误。e、 g.将其从Collection
更改为String
可以消除错误。即使使用原始类型也可以。在我看来,Supplier getSupplier()
或Supplier getSupplier()
必须与擦除Supplier getSupplier()
的签名相同。这对我来说没有意义。你基本上说带参数的方法不能覆盖其他方法,这显然是错误的。读我写的东西。我说添加参数使其成为重载而不是覆盖。根据定义,这是非常基本的。在A.getSuppliers
和B.getSuppliers
之间更改了哪些参数?
public abstract class A {
public abstract <X> Supplier<X> getSuppliers(Collection<String> strings);
public static class B extends A {
@Override
public Supplier<String> getSuppliers(Collection<String> strings) {
return String::new;
}
}
}
A b = new B();
URL url = b.<URL>getSupplier().get();
<X>getSupplier() in A (m2)
1st snippet
getSupplier() in B (m1)
<X>getSuppliers(Collection<String> strings) in A (m2)
2nd snippet
getSuppliers(Collection<String> strings) in B (m1)
getSuppliers(Collection<String> strings);
getSuppliers(Collection strings);