当前位置: 首页 > 面试题库 >

重写Java中具有泛型参数的方法?

郎灿
2023-03-14
问题内容

我有一个抽象类 Monitor.java ,它由类 EmailMonitor.java 子类

方法:

public abstract List<? extends MonitorAccount> performMonitor(List<? extends MonitorAccount> accounts)

Monitor.java中 定义,并且必须在 EmailMonitor.java中 覆盖。

我目前在 EmailMonitor.java中 重写了如下方法:

@Override
public List<EmailAccount> performMonitor(List<EmailAccount> emailAccounts) {
    //...unrelated logic
    return emailAccounts;
}

但是,这会产生编译时错误:

Name clash: The method performMonitor(List<EmailAccount>) of type EmailMonitor has the same erasure as performMonitor(Lis<? extends MonitorAccount> emailAccounts) of type Monitor but does not override it

EmailAccount是的子类MonitorAccount,因此(至少在我看来)以这种方式覆盖它是很有意义的。看到编译器对我的逻辑不满意,我应该如何正确处理此问题,同时还要保持编译时间检查以确保所有调用都EmailMonitor.performMonitor()接收List
EmailAccount而不是其他类型的List MonitorAccount


问题答案:

不,它没有适当地覆盖它。覆盖意味着您应该能够处理对基类的任何有效输入。考虑如果客户这样做,会发生什么情况:

Monitor x = new EmailMonitor();
List<NonEmailAccount> nonEmailAccounts = ...;
x.performMonitor(nonEmailAccounts);

鉴于您的描述,其中没有应该给出编译时错误的东西-但这显然是错误的。

在我看来,Monitor应该监视的帐户类型应该是通用的,因此您EmailMonitor应该扩展Monitor<EmailAccount>。所以:

public abtract class Monitor<T extends MonitorAccount>
{
    ...
    public abstract List<? extends T> performMonitor(
        List<? extends T> accounts);
}

public class EmailMonitor extends Monitor<EmailAccount>
{
    @Override
    public abstract List<? extends EmailAccount> performMonitor(
        List<? extends EmailAccount> accounts)
    {
        // Code goes here
    }
}

但是,您可能需要仔细考虑performMonitor调用中的泛型-表示什么的返回值是什么?



 类似资料:
  • 问题内容: 在C#中,我实际上可以这样做: 但是由于某种原因,我无法使其在Java中工作。 我要做的是在超类上创建一个静态方法,以便可以将子类转换为XML。 问题答案: 称为: 或更明确地: 更令人困惑的是,您可以拥有既构造泛型类型又具有泛型参数的构造函数。不记得该语法,也从未在愤怒中使用过它(无论如何,最好还是使用静态创建方法)。 强制转换是不安全的,并且您不能编写T.class。因此,将T.c

  • 我正在尝试覆盖子类中从父类继承抽象方法的方法。我正在尝试更改泛型返回类型,但我有点困惑。 基本泛型类: 儿童班: 实施: 我想在其中覆盖参数化方法的子视图类: 这是Eclipse抛出错误消息的地方: 注意类和接口:事件和级别: 以及继承自 的 Model 类 我试图实现的是编写更抽象的代码,因为这些类、接口将被多个类扩展(在我的例子中是不同的视图类型)。这些是抽象类:< code>BaseAdap

  • 来自Java文档:在类C中声明的实例方法m1覆盖在类A中声明的另一个实例方法m2,如果以下所有条件都为真:。。。。。m1的签名是m2签名的子签名(§8.4.2)。 方法m1的签名是方法m2签名的子签名,前提是:m1的签名与m2签名的擦除相同(§4.6)。 是对一个 如果是这样,什么是错的? EDIT1:或者如果我切换通用类型: 这种情况下有什么问题? EDIT2:我知道如何修复它,但我想了解,在这

  • 这是如何编译的: 但这并不是: 它给我以下编译错误: Impl不是抽象的,并且不会覆盖测试中的抽象方法getValue(整数) 错误:名称冲突:Impl中的getValue(T)和测试中的getValue(Integer)具有相同的擦除,但两者都不重写另一个 擦除不能确保t被整数替换吗?那么为什么第二个例子是无效的呢?

  • 安吉丽卡·兰格(Angelica Langer)在关于仿制药的常见问题解答中说(参见Technicalities.FAQ822): 如果这些方法具有具有不同边界的类型参数,则它们不会重写,因为这些方法的签名不是重写等价的。请记住,类型参数边界是泛型方法签名的一部分。 示例(泛型子类型方法重载泛型超类型方法;不推荐): 我不明白为什么方法在类中重载。据我所知,这应该是一个编译时错误,因为在和中具有相

  • 我正在做一个体验,尝试用以下方式重写泛型类的方法: 为什么我不能?编译错误是 yGenFun。java:15:错误:对doX的引用不明确,Do中的方法doX(A)和MyGenFun中的方法doX(T)都匹配x.doX(“测试”);^其中A、T是类型变量:在类Do T中声明的extends对象扩展在类MyGenFun 1 error中声明的CharSequence 如果我注释“第1行”,我可以编译代