我想知道为什么这是一个有效的覆盖:
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> getSuppliers(Collection<String> strings);
public static class B extends A {
@Override
public Supplier<String> getSuppliers(Collection<String> strings) {
return String::new;
}
}
}
根据JLS§8.4.8.1,B.getSupplier
必须是子签名a.getSupplier
:
C类中声明或继承的实例方法mC重写C类中声明的另一个方法mA,如果以下所有为真:
子签名在JLS§8.4.2中定义:
两个方法或构造函数,M和N,如果具有相同的名称、相同的类型参数(如果有的话),则具有相同的签名(§8.4.4),并且,在将N的形式参数类型适应M的类型参数之后,具有相同的形式参数类型。
方法m1的签名是方法m2签名的子签名,如果:
因此,似乎B.getSupplier
是a.getSupplier
的子签名,但B.getSuppliers
不是a.getSuppliers
的子签名。
我不知道怎么会是这样。
如果B.getSupplier
是a.getSupplier
的子签名,因为它具有相同的擦除,那么B.getSuppliers
也必须具有与a.getSuppliers
相同的擦除。这应该足以覆盖getSuppliers
,使其合法-但事实并非如此。
如果B.getSupplier
是a.getSupplier
的子签名,因为它具有相同的签名,那么我想知道“相同类型参数(如果有)”的确切含义是什么。
如果考虑类型参数,则它们应该具有不同的类型参数:A.getSupplier
具有类型参数X
,B.getSupplier
没有
如果不考虑类型参数,那么getSuppliers
有什么不同?
这更像是一个关于覆盖和泛型的学术问题,所以请不要建议重构代码(比如将类型参数X
移动到类等)。)。
我正在寻找一个正式的,基于JLS的答案。
在我看来,B.getSupplier
不应该能够覆盖A.getSupplier
,因为它们没有相同的类型参数。这使得以下代码(产生ClassCastException
)合法:
A b = new B();
URL url = b.<URL>getSupplier().get();
添加参数的那一刻,它就不再是重写,而是过载。
泛型与此无关。
根据编译器输出,两个示例中的方法签名不同(使用-Xlint:unchecked
选项编译代码以确认):
<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)
根据JLS规范,方法m1的签名是方法m2签名的子签名,如果:
>
m2与m1具有相同的签名,或
m1的签名与删除m2的签名相同。
第一种说法是出局——方法签名不同。但是第二个语句和擦除呢?
(m1)是A的子签名。
<代码>
(m1)不是A的子签名。
m1的签名:
getSuppliers(Collection<String> strings);
删除m2的签名:
getSuppliers(Collection strings);
从集合更改m1参数
第一
第二个代码片段(无效覆盖):方法签名最初是不同的,在对父方法应用擦除后仍然不同。
我试图创建一个返回泛型类型参数的方法。 我有一个类车辆订单扩展抽象类订单。在类订单中,我创建了一个抽象方法接收HiredObject。这个方法不会接收任何参数,并将返回一个泛型。 我在VehicleOrder类中实现了这个方法,并将其设置为返回类参数vehicle。 问题是,当我实例化一个新的VeilceOrderorororororororororororororderororororororo
我有一个问题,从抽象类中重写泛型方法。 这是我的抽象类: 当我创建类(B)来实现类(a)时,如下所示: 显示了(getData)方法中的以下编译错误: ”“B。getData“(“字符串函数(字符串)”不是“a”的有效重写。getData'('字符串函数(类型)‘)。dart(无效覆盖) 以及返回语句中的此错误: 类型为“String”的值不能从方法'getData'返回,因为它的返回类型为'St
我试图创建一个Java方法,它接受一个对象类型和它应该转换成的数据类型。 例如,如果我应该能够返回一个值1作为Int或双根据需要。我使用类传递数据类型作为参数。 问题:如何使方法泛型以接受基于输入参数的返回类型? 下面的代码只是一个示例,它可能在语法上不正确,用于解释我的问题。
我正在做一个体验,尝试用以下方式重写泛型类的方法: 为什么我不能?编译错误是 yGenFun。java:15:错误:对doX的引用不明确,Do中的方法doX(A)和MyGenFun中的方法doX(T)都匹配x.doX(“测试”);^其中A、T是类型变量:在类Do T中声明的extends对象扩展在类MyGenFun 1 error中声明的CharSequence 如果我注释“第1行”,我可以编译代
可以使用泛型将返回类型与参数类型匹配吗? 实例案例: 我有一个抽象类,可以从不同的POJO导入数据,这个类包含一个abstract方法importData。 importData返回的对象必须与传递给该方法的对象类型相同。 由于抽象方法的每个实现的对象类型不同,并且类型不扩展另一个,如何定义抽象方法,以便实现返回类型和传递类型必须匹配? 经过考验: 结果: 方法的返回类型不必与传递的对象类型匹配。