Il meccanismo covariant return types permette in Java di restituire un tipo non esattamente uguale a quello della superclasse durante l'override di un metodo, ma un suo sottotipo (covariant type).
Questo aumenta l'espressività del codice, consentendo di ottenere tipi più specifici senza bisogno di casting esplicito.
Esempio:
class Animal { } class Dog extends Animal { } class Parent { Animal getAnimal() { return new Animal(); } } class Child extends Parent { @Override Dog getAnimal() { return new Dog(); } // Restituzione covariante }
Condizioni per funzionare:
È possibile cambiare il tipo restituito di un metodo sovraccaricato (overloaded method) in una sottoclasse rendendolo un sottotipo della classe base? Sarebbe considerato un sovraccarico valido?
Risposta: No, per il sovraccarico (overloading) conta solo la firma dei parametri, mentre il tipo restituito non ha importanza. Non è possibile modificare solo il tipo restituito in un sovraccarico: tale metodo entrerà in conflitto per la firma.
Esempio:
class Example { Animal make() { return new Animal(); } // Dog make() { return new Dog(); } // Errore di compilazione: metodo duplicato! }
La covarianza funziona solo per l'override.
Storia
In un progetto, il programmatore ha commesso un errore aggiungendo un metodo sovraccaricato con lo stesso nome e parametri, ma con un diverso tipo restituito, aspettandosi che fosse un "override covariante". Di conseguenza, il progetto non si compilava e il bug è stato scoperto solo durante il CI.
Storia
Usando il return covariante in una gerarchia di classi, lo sviluppatore ha applicato erroneamente i tipi parametrici (generics), non implementando correttamente i sottotipi, il che ha portato a un errore ClassCastException durante l'esecuzione quando si lavorava con delle collezioni.
Storia
Nel metodo sovrascritto veniva restituito un tipo più specializzato, ma il team non ha documentato questo contratto. Nel codice che lavorava tramite il tipo base, si sono verificati problemi di casting e comportamenti inaspettati durante l'"upcast" dei riferimenti, portando a una serie di errori nascosti.