equals e metodi hashcode autogenerati, è sempre una buona pratica?

2

Premessa: diciamo che il mio obiettivo è coprire tutte le mie classi con la copertura del test.

Nonostante l'opinione comune (specialmente nella comunità Java) di "non prestare troppa attenzione alla complessità ciclica (CC) e alla copertura del codice", penso davvero che queste informazioni siano estremamente utili: quando si ha un CC molto alto, o una zona scoperta nel tuo codice, molto probabilmente hai scritto un codice morto, o è un odore che hai problemi nel design. Nella mia esperienza personale posso dire che molti codici morti è odore di codice.

Questo problema diventa un po 'complicato quando si ha a che fare con il codice generato automaticamente, e questo è il punto, come posso affrontare facilmente i metodi hashcode e equals autogenerati? Mi sono imbattuto in questa domanda in StackOverflow e ho realizzato un ottimo punto:

link

Ma questa domanda non è un duplicato perché voglio usare un approccio diverso:

Le migliori opzioni disponibili nelle risposte di quella domanda sono, per quanto posso vedere, EqualsBuilder di Apache Commons Lang o http://code.google.com/p/guava-libraries/ Guava. Entrambi usano il reflection (correggimi se sbaglio) e questo potrebbe essere un problema per le prestazioni in alcune situazioni.

Ma la mia domanda attuale è: poiché la maggior parte delle volte i metodi equals e hashcode sono non coperti, è un suggerimento che questa particolare classe fa non hanno bisogno di quei 2 metodi? Poiché molti sviluppatori Java generano molto tempo uguali e codice hash anche quando non è necessario, cosa mi manca? Non dovrebbe essere una soluzione migliore per generare quei metodi solo quando hai bisogno, ad esempio, di ordinare gli oggetti di quella classe, di usare quegli oggetti come una chiave di Hashtable e così via?

Come ho detto, penso che gli obiettivi di bassa complessità e alta copertura siano ammirevoli, ma la soluzione per utilizzare EqualsTester , mi sembra" Forza di coprire il codice che non è effettivamente necessario nel tuo programma ".

    
posta thermz 10.02.2014 - 15:29
fonte

1 risposta

4

La storia di equals() combina diverse decisioni di design sfortunate che sono ora impossibili da cambiare e che ogni utente Java deve semplicemente vivere in un modo o nell'altro: è profondamente intessuto nella semantica dei tipi di contenitori standard, viene automaticamente ereditato da ogni classe definita dall'utente ma con un comportamento che di solito non è quello che si desidera e definendolo senza definire anche hashCode() genera in modo non definito un comportamento (ad esempio, la lingua impone determinati requisiti all'utente ma non ha alcun modo di avvertire te se sono insoddisfatti.)

Tu puoi andare d'accordo semplicemente non definendo mai il metodo SE non usi mai tali oggetti in alcun luogo che esponga il comportamento indesiderato. Ma poiché lo sviluppo del software è un gioco cooperativo, ciò richiede una regola disciplinata di "Assolutamente no Foo in Set s, mai!" che tutti coloro che sono coinvolti con il codice devono conoscere e seguire il 100%.

Può valere la pena imporre una tale regola per ottenere un certo rendimento, proprio come con altri principi fondamentali della codifica - ad es. "Nessun valore di ritorno null , mai!" è una strategia comune per risparmiare un sacco di controllo per null . Ma questo dipende da quanto guadagni davvero dalla piccola semplificazione per ogni classe. Il rovescio della medaglia è che hai aggiunto un'ipotesi inespressa che tutti gli utenti della tua classe devono conoscere e seguire, o soffrire silenziosamente di un comportamento indefinito.

    
risposta data 10.02.2014 - 15:40
fonte