首页 文章

Java名称冲突错误,一种方法与另一种方法具有相同的擦除

提问于
浏览
0

我有两个课程如下

class QueryResult:

public class QueryResult
{
...
public static List sortResults(boolean ascending, List<QueryResult> toSort)
    {   ...
    }
}

和类CaseResult:

public class CaseResult extends QueryResult
{
...
public static List sortResults(boolean ascending, List<CaseResult> toSort)
    {   ...
    }
}

我收到以下错误:

名称冲突:CaseResult类型的方法sortResults(boolean,List)与QueryResult类型的sortResults(boolean,List)具有相同的擦除,但不隐藏它CaseResult.java

我在类似问题Java generics name clash , has the same erasure下尝试了答案,但错误更多 . 我想我可能会误解某些东西,或者那些答案不适合我的情况 .

有人可以提供任何解决方案或解释更多,以帮助我理解?谢谢你们 .

2 回答

  • 0

    根据Java Documentation

    如果子类定义的静态方法与超类中的静态方法具有相同的签名,则子类中的方法会隐藏超类中的方法 .

    隐藏静态方法和覆盖实例方法之间的区别具有重要意义:

    • 被调用的重写实例方法的版本是子类中的版本 .

    • 被调用的隐藏静态方法的版本取决于它是从超类还是从子类调用的

  • 0

    Darshit Chokshi的回答涵盖了错误的原因 . 但是,由于尚未发布解决方案/替代方案,请尝试以下操作:

    您试图以这种方式覆盖sortResults()方法,以便您可以使用不同的元素对列表进行排序 . 但是,当覆盖时,您需要具有相同的类型签名 . 签名在您的情况下看起来类似,但由于List中的元素不同 - 编译器实现List <QueryResult>和List <CaseResult>不同,但由于Java中的类型擦除,它将不确定它应该调用哪个方法 - 即它应该调用超类方法还是子类方法 .

    而不是覆盖,而是更改超类中的原始方法(在您的情况下,QueryResult),以便它可以处理任何类型的List元素 . 您可以使用通配符捕获来完成此任务:

    public class QueryResult {
    ...
    public <T> static List<T> sortResults(boolean ascending, List<T> toSort) {   
        ...
        }
    }
    

    此方法接收一个列表并将推断元素类型,将元素类型分配给泛型类型参数T.每当您想要引用方法体中的元素类型时,而不是使用元素类型名称(之前要么QueryResult或CaseResult),现在你将使用泛型类型变量T.

    如果需要,你也可以在这个变量上放置更多的边界(即如果list元素需要是QueryResult的子类型,你可以说<T扩展QueryResult>),这将迫使Java对List进行类型检查以及什么类型的它可能有的元素 .

    对原始代码的进一步评论 . 在新的通用代码中使用原始类型要非常小心 - 您将列表作为原始类型返回:List,而不指定列表的元素类型是什么,即参数化类型:List <SomeActualType> . 这可能会导致许多问题,因此不建议这样做 . Java创建者在Java中保留了这种编码形式,以便向后兼容泛型之前存在的代码,但强烈建议不要以这种方式编写新的编写代码 .

    您可以在教科书中阅读有关原始类型与参数化类型的更多信息以及使用原始类型的缺陷,以及有关通配符捕获和边界的更多信息:

    Effective Java, by Joshua Bloch
        Section: Generics
        Item 23: Don't use raw types in new code
        Item 28: Use bounded wildcards to increase API flexibility
    

相关问题