2014-04-25 9 views
7

Ok, così ho capito il motivo per cui dovremmo dichiarare un argomento per essere definitiva da this question, ma non capisco il motivo per cui non dovremmo ...Perché non tutti gli argomenti della funzione devono essere dichiarati definitivi?

Dal Java utilizza sempre passaggio per valore, questo significa che possiamo restituire un nuovo valore attraverso l'argomento specificato, possiamo solo sovrascriverlo e rendere inutile l'argomento, perché non usiamo il valore passato ...

È l'unico vantaggio del metodo non finale argomenti in Java il fatto che non devi fare una variabile locale del tipo 'argomenti'?

P.S. Questa domanda è stata attivata dalla regola PMD di MethodArgumentCouldBeFinal

+0

È possibile sostituire il valore passato per un oggetto alternativo in determinate circostanze. Ma sì, è raro –

+7

Non sempre "rendere il parametro" (non argomento) inutile. Ad esempio, è * ragionevolmente * comune eseguire alcune normalizzazioni di input, riutilizzando il parametro: 'text = StringUtil.nullToEmpty (text);' ad esempio. –

+2

A proposito, uno dei punti nella risposta alla domanda collegata, che devi contrassegnare un argomento 'final' per usarlo in una classe interna anonima, non è più vero in Java 8. – ajb

risposta

4

mi viene in mente solo 2 motivi non fare un parametro final:

  1. per salvare l'utilizzo di una variabile locale se è necessario sovrascrivere il valore del parametro in alcuni casi limite (per esempio inserire un valore predefinito se il parametro è nullo ecc.). Tuttavia, non considererei una buona pratica in generale.

  2. per salvare 6 caratteri per parametro, che migliora la leggibilità.

La ragione 2 è ciò che mi porta a non scriverlo la maggior parte del tempo. Se si presume che le persone seguano la pratica di non assegnare mai un nuovo valore a un parametro, è possibile considerare tutti i parametri come implicitamente final. Naturalmente, il compilatore non ti impedirà di assegnare un parametro, ma posso conviverci, visto il guadagno in termini di leggibilità.

+0

Re # 2: esiste un'impostazione Eclipse per aggiungere 'final' a tutti i parametri per impostazione predefinita? Ciò farebbe risparmiare un po 'di battitura. :) – ajb

+1

@ajb C'è un'impostazione di eclissi per inserirli (quando possibile) nella fonte "ripulire", di sicuro. Per quanto riguarda il loro inserimento di default sul codice generato automaticamente, non lo so. Ad ogni modo, stavo piuttosto parlando del risultato visivo, non della battitura della parola. – Joffrey

+3

Java sarebbe meglio se tutte le variabili fossero definitive di default e fosse necessaria una parola extra per renderle mutabili –

1

Impedisce all'utente di commettere un errore non intenzionale nel codice. La regola generale è di rendere ogni campo e ogni argomento di funzione che sai che non dovresti cambiare (intendo riferimento, puoi ancora cambiare valore) nel tuo codice come finale.

Quindi fondamentalmente è un modo per impedire al programmatore di riprendere il piede. Niente di più.

+3

La domanda posta si riferisce a quale sarebbe il vantaggio di * non * usando l'ultimo –

+0

@Vlad Più flessibilità e libertà per il programmatore. Come in molte costruzioni PL, che avrebbero potuto essere più rigorose. –

1

Se si deve dichiarare una variabile locale final o meno (il parametro metodo è compreso in questo), è più del requisito che una convenzione. Non riceverai una risposta certa dicendo che dovresti sempre usare final o non dovresti mai usare final. Perché questa è davvero una preferenza personale.

Personalmente contrassegno i parametri o le variabili locali final quando davvero non voglio che i loro valori siano modificati, e mostra anche la mia intenzione agli altri sviluppatori di non sovrascrivere i valori. Ma non lo faccio per tutti i parametri. Anche per alcuni, l'utilizzo di final sembra essere un disturbo, in quanto ciò aumenta realmente la base di codice.

0

Regola generale: non utilizzarlo.

Final non può fermarti a cambiare oggetti, solo il suo riferimento, e questo perché gli oggetti in java sono, di solito, non immutabili.

Date un'occhiata a questo codice:

class Example{ 
// think about this class as a simple wrapper, a facade or an adapter 
SomeClass inner = new SomeClass(); 
setInnet(Someclass inner){ 
    this.inner = inner; 
} 
// delegate methods..... 
} 

Ora, in un metodo:

private void (final Example examp){ 

.... 

examp sarà sempre lo stesso oggetto, ma può variare a inner ... Ed è il inner oggetto importante qui, quello che rende tutto!

Questo potrebbe essere un esempio estremo e si potrebbe pensare che inner potrebbe essere definitivo ma, se è una classe utillery, forse non dovrebbe. Inoltre è facile trovare un esempio più comune:

public void (final Map map){; 
.... 
//funny things 
.... 
//and then, in a line, someone does: 
map.clear() 
// no we have the same reference... but the object has change... 
.... 

Quindi, il mio punto contro final negli argomenti è che non è garantito che tutto il codice all'interno di una classe final è inmutable e così la parola final può finire si trova e che mascarading un bug ...

Inserendo final in parametri puoi mostrare solo i desideri, non i fatti, e per questo dovresti usare i commenti, non il codice. Inoltre: è uno standard (di fatto) in Java che tutti gli argomenti sono solo argomenti di input (99% del codice). Pertanto, la parola final in param è NOISE perché esiste e non significa nulla.

E il rumore non mi piace. Quindi cerco di evitarlo.

Uso solo la parola final per contrassegnare le variabili interne che verranno utilizzate in una classe interna anonima (è possibile evitare di contrassegnarlo se sono effettivamente definitive, ma è più pulito e più leggibile).

AGGIORNAMENTO

mezzi finali assegnati una volta 'che in applicata ad argomenti metodo significa nulla nella logica di un programma, né nella sua progettazione.

È possibile assegnare gli argomenti a un nuovo oggetto all'interno di un metodo e all'esterno non ci saranno cambiamenti.

L'unica differenza nel mettere gli argomenti finali è che non sarà possibile assegnare quelle entità a un altro oggetto. Assegnare argomenti è qualcosa che può essere brutto e qualcosa da evitare, ma è solo un problema di stile e, a quel punto, il problema di stile dovrebbe essere l'assegnazione stessa e non l'ausilio della parola 'finale'.

Penso che la finale sia inutile in argomenti (e quindi, rumore), ma se qualcuno è in grado di trovarne un uso, sarò felice di impararlo. Cosa posso ottenere mettendo 'finale' che non può raggiungere senza metterlo?

+0

Quindi la tua ragione contro 'finale' è che tu (o altri) non capisci il suo significato (che può essere un argomento valido)? 'final' non significa né implica oggetti immutabili, quindi *" la parola 'finale' può finire per mentirti "* è vera solo per qualcuno che non sa cosa significa" finale ". * "mascarading a bug" * è abbastanza poco chiaro, perché quando il bug è che un metodo muta un oggetto, allora succederà per entrambi i parametri 'final' e non -final'. * "Inserendo' final' in params puoi solo mostrare desideri, non fatti "* Questo è anche sbagliato, perché il valore del parametro è' final' e questo è un dato di fatto. – Tom

+0

@Tom prima del downvoting, per favore leggi il post collegato nella domanda e vedrai quali sono i due motivi sostenuti per usarlo e che ho parlato di uno di loro ... Ad ogni modo, aggiornerò la domanda spiegando perché, dal mio punto di vista, la parola finale è solo rumore usato in args secondo la sua definizione. – inigoD

+0

Hai scritto che pensi che 'final' sia rumore, perché può portare a false ipotesi sull'immutabilità degli oggetti passati e che non saranno mutati nel metodo. Il problema qui è lo sviluppatore, non 'final'. 'final' non implica nulla sull'oggetto di riferimento, limita solo la variabile stessa (il tuo aggiornamento lo copre). Dato che stai chiedendo un esempio: un bug abbastanza comune su SO (per la programmazione dei newbies credo) è questo 'public MyBlubClass (String arg) {arg = arg; } '. Come puoi vedere, dovrebbe essere 'this.arg = arg'. Un 'final' per il parametro rileverà che – Tom