Fondamentalmente, i tipi Java non si propagano sempre bene. Se in qualsiasi momento, passi a Object
, perdi informazioni sui tuoi tipi (questo potrebbe non essere sempre vero in un blocco che il compilatore può analizzare). E non puoi sempre evitare Object
, a causa di generici.
Dettagli
Se guardiamo Implementazione di OpenJDK , il commento dice:
- Gli oggetti devono implementare
Comparable
- Gli oggetti devono essere comparabili tra loro: non puoi confrontare
String
e Integer
istanze.
Entrambi i controlli possono essere eseguiti in fase di esecuzione (generando eccezioni se necessario).
Ciò che suggerisci consente di eseguire il primo controllo durante la compilazione.
Tuttavia, dobbiamo considerare il metodo in relazione al suo utilizzo e, sfortunatamente, non puoi sempre conoscere il tipo di alcuni oggetti.
Originariamente ho scritto un esempio con List<String>
e toArray
, che restituisce un Object[]
. La conversione in Object[]
non consente di chiamare sort
e non ho visto un modo semplice per convertire Object[]
in String[]
. Grazie ai commenti di SJuan76, ecco come farlo:
String[] strings = names.toArray(new String[0]);
Quindi strings
, grazie alla covarianza dell'array, è adatto per il confronto. Tuttavia, questo approccio non è favorevole allo sviluppo. Inoltre, non può essere distratto da costrutti linguistici: i generici usano tecniche di cancellazione del tipo che introducono istanze di Object
.
A proposito, dimentichiamoci dei generici per un momento: dopo tutto, le prime versioni di Java, per le quali è stato implementato sort
, non hanno fornito i generici.
Come già detto, il tipo di codice scritto sopra non è certamente conveniente per l'uso. Ma ancora più importante, anche se è controllato in fase di compilazione, sono abbastanza sicuro che non è ottimizzato: c'è ancora un'operazione di copia in array in runtime: non si vuole scrivere un'API che impone questo tipo di costo a l'utente (considerare anche le prestazioni delle macchine virtuali originali).
Quindi, è meglio accettare semplicemente più parametri ed eseguire controlli in modo dinamico. Poiché, comunque, il punto (2) precedente richiede già verifiche di runtime e probabilmente genera eccezioni, potremmo anche accettare Object[]
e tipi di test in fase di esecuzione.
Ora, potresti pensare che il fatto che alcune funzioni perdano informazioni di tipo come toArray
(senza argomenti) è di per sé sfortunato, ma a questo punto è più un problema del sistema dei tipi di linguaggio.