Java name clash error, a method has the same erasure as another method

心已入冬 提交于 2019-12-12 05:56:54

问题


I have two classes as follows

class QueryResult:

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

and class CaseResult:

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

I am getting the following error:

Name clash: The method sortResults(boolean, List) of type CaseResult has the same erasure as sortResults(boolean, List) of type QueryResult but does not hide it CaseResult.java

I tried answers under the similar question Java generics name clash , has the same erasure but got more errors. I think I may misunderstand something or those answers do not fit my case.

Could someone please provide any solutions or explain more to help me understand? Thank you all.


回答1:


As per Java Documentation,

If a subclass defines a static method with the same signature as a static method in the superclass, then the method in the subclass hides the one in the superclass.

The distinction between hiding a static method and overriding an instance method has important implications:

  • The version of the overridden instance method that gets invoked is the one in the subclass.
  • The version of the hidden static method that gets invoked depends on whether it is invoked from the superclass or the subclass



回答2:


The reason for the error is covered in Darshit Chokshi's answer. However, since a solution/alternative has not been posted yet, try the following:

You are trying to override the sortResults() method in such a way so that you can sort lists with different elements. However, when overriding you need to have the same type signature. The signature looks similar in your case, but since the elements in the List differ - the compiler realises List< QueryResult> and List< CaseResult> is different, but due to type erasure in Java, it would be uncertain which method it should be calling - i.e. should it call the super class method or the subclass method.

Instead of overriding, rather change the original method in the super class (in your case, QueryResult) so that it can handle anytype of List element. You can use wildcard capturing to accomplish this:

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

This method receives a list and will infer the element type, assigning the element type to the generic type parameter T. Whenever you then want to refer to the element type in the body of the method, instead of using the element type name (previously either QueryResult or CaseResult), now you would use the generic type variable T instead.

You can also put further bounds on this variable if required (i.e. if the list element needs to be a subtype of QueryResult you can say < T extends QueryResult>), this will force Java to do a type check on the List and what type of elements it may have.

A further comment on your original code. Be very careful of using raw types in new generic code - you are returning a list as a raw type: List, without specifying what the element type of the list is i.e. a parameterised type: List< SomeActualType>. This can cause many problems and is not advised. The Java creators kept this form of coding in Java for backward compatibility of code that existed before generics, but it is strongly advised not to code in this manner for new written code.

You can read up more about the raw type vs parameterised type and the pitfalls of using raw types, as well as more information on wildcard capturing and bounds, in the textbook:

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


来源:https://stackoverflow.com/questions/44939290/java-name-clash-error-a-method-has-the-same-erasure-as-another-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!