簡體   English   中英

Java名稱沖突錯誤,一種方法與另一種方法具有相同的擦除

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

我有兩個班,如下

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泛型名稱clash的類似問題下嘗試了答案盡管擦除相同,但出現了更多錯誤。 我認為我可能會誤會某些東西,或者這些答案不適合我的情況。

有人可以提供任何解決方案或進一步解釋以幫助我理解嗎? 謝謝你們。

該錯誤的原因已在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

根據Java文檔

如果子類定義的靜態方法具有與超類中的靜態方法相同的簽名,則子類中的方法會將其隱藏在超類中。

隱藏靜態方法和覆蓋實例方法之間的區別具有重要意義:

  • 被調用的重寫實例方法的版本是子類中的版本。
  • 調用的隱藏靜態方法的版本取決於是從超類還是從子類調用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM