Personalmente, usavo sempre final
sempre (di questi tempi, di volta in volta) solo per garantire che le variabili non venissero riassegnate; niente di più, niente di meno.
Il vantaggio di non riassegnare le variabili è importante per me in realtà, poiché scoraggia la "stampella" delle variabili temporanee. Questo a sua volta mi incoraggia a riesaminare il mio codice per codice ripetitivo (sostituendoli con metodi in linea, o anche a ri-strutturarli) ed elimina potenziali bug dovuti a ritardi incauti.
Quest'ultimo è più utile nei metodi long do-it-all, ma una volta scomposto in metodi più piccoli, è più facile vedere l'ambito delle variabili e quindi anche meno probabilità di riassegnarle in primo luogo. Quindi la mia preferenza personale per usarli di meno ora.
Per affrontare la tua preoccupazione sull'accettazione di oggetti mutevoli / immutabili, il mio suggerimento è di renderne uno l'approccio predefinito per la tua libreria / base di codice, attenersi a quello e quindi documentare l'eccezione. In altre parole, se per impostazione predefinita è meglio passare oggetti immutabili, è possibile renderlo chiaro così dal tipo di documentazione "Per iniziare" per risolvere questo codebase-wide. Puoi quindi utilizzare il suggerimento di @ assylias per documentare i metodi per dire qualcosa del tipo:
/**
* This method works with mutable arguments as well.
*/
o
/**
* The side-effect of this method modifies the mutable arguments.
*/
Puoi anche giocare con il nome della tua classe chiamandoli MyImmutableType
(ad esempio). Generalmente lo evito perché i loro nomi non "rotolano bene", ma YMMV.
// this has to return a new MyImmutableType instance
public MyImmutableType doSomething(MyImmutableType input);
// this possibly mutates the mutable argument, which the caller will then use
public void doSomething(MyMutableType input);
Forse ancora più importante , final
anche le tue classi di argomenti in modo che se i chiamanti / utenti della tua base di codice decidono di controllare il tuo codice sorgente, allora possono anche dire immediatamente che la classe è immutabile.
public final class Wrapper<T> {
private final int id;
private final T payload;
public Wrapper(int id, T payload) {
this.id = id;
this.payload = payload;
}
}
In conclusione , se vedo una parola chiave final
nella firma del metodo, tutto quello che so è che lo sviluppatore sta facendo qualcosa giusto non (potenzialmente) riassegnando argomenti del metodo all'interno del metodo. Non dovrebbe essere invocato per indicare se gli argomenti dovrebbero / devono essere immutabili.