Questa regola ha lo scopo di evitare conflitti nel codice legacy che utilizza ancora tipi non elaborati.
Ecco un esempio del perché ciò non era consentito, tratto dal JLS. Supponiamo, prima che i generici fossero introdotti a Java, ho scritto un codice come questo:
class CollectionConverter {
List toList(Collection c) {...}
}
Estendi la mia classe, in questo modo:
class Overrider extends CollectionConverter{
List toList(Collection c) {...}
}
Dopo l'introduzione dei farmaci generici, ho deciso di aggiornare la mia biblioteca.
class CollectionConverter {
<T> List<T> toList(Collection<T> c) {...}
}
Non sei pronto per effettuare aggiornamenti, quindi lasci la tua Overrider
classe da solo. Per sostituire correttamente iltoList()
metodo, i progettisti del linguaggio hanno deciso che un tipo grezzo era "equivalente a sostituzione" di qualsiasi tipo generato. Ciò significa che sebbene la firma del tuo metodo non sia più formalmente uguale alla firma della mia superclasse, il tuo metodo ha ancora la precedenza.
Ora passa il tempo e decidi di essere pronto per aggiornare la tua classe. Ma fai un po 'di casino e invece di modificare il toList()
metodo raw esistente, aggiungi un nuovo metodo come questo:
class Overrider extends CollectionConverter {
@Override
List toList(Collection c) {...}
@Override
<T> List<T> toList(Collection<T> c) {...}
}
A causa dell'equivalenza di sostituzione dei tipi non elaborati, entrambi i metodi sono in una forma valida per ignorare il toList(Collection<T>)
metodo. Ma ovviamente, il compilatore deve risolvere un singolo metodo. Per eliminare questa ambiguità, alle classi non è consentito disporre di più metodi che sono equivalenti a override, ovvero più metodi con gli stessi tipi di parametri dopo la cancellazione.
La chiave è che questa è una regola del linguaggio progettata per mantenere la compatibilità con il vecchio codice utilizzando tipi non elaborati. Non è una limitazione richiesta dalla cancellazione dei parametri di tipo; poiché la risoluzione del metodo si verifica in fase di compilazione, l'aggiunta di tipi generici all'identificatore del metodo sarebbe stata sufficiente.