Sì, se hai chiamato myMethod()
10 volte creerà 10 oggetti unici e separati.
La parola chiave new
fa esattamente quello che dice sul tin, crea un oggetto nuovo di zecca, indipendentemente dal fatto che ne esista già uno. Crea un nuovo oggetto e infila il riferimento a quell’oggetto all’interno della variabile che è stata data, sovrascrivendo qualsiasi valore precedente (oggetto) della variabile detenuta.
La variabile myObject viene riallocata ogni volta?
Di nuovo, sì, verrebbe riassegnato con un nuovo oggetto ogni volta che veniva chiamato il metodo. Una nota interessante su questo sarebbe che la variabile non sarebbe “realmente” riassegnata mentre si sta definendo la variabile all’interno del corpo del metodo stesso, quindi ogni volta che il metodo termina rimuoverà le variabili che sono state definite all’interno del suo ambito. Quindi quello che in realtà fa è creare 10 variabili individuali e assegnare 10 singoli oggetti, anche se come ho detto gli altri avrebbero dovuto essere rimossi automaticamente in modo da non utilizzare alcuna memoria aggiuntiva.
In poche parole: dovrei scrivere codice del genere solo se ho intenzione di invocare quel metodo solo una volta?
Bene, come ho detto, nell’esempio sopra ogni oggetto verrebbe distrutto alla fine dell’esecuzione del metodo (supponendo che tu non abbia assegnato il riferimento all’oggetto a una variabile al di fuori dell’ambito del metodo) quindi nel tuo esempio potresti chiamare felicemente il metodo tutte le volte che volevi, ma ogni volta non sarebbe in alcun modo connesso alle chiamate precedenti.
Mi rendo conto che il mio modo di scrivere può essere fonte di confusione, quindi se vuoi che chiarisca qualcosa basta chiedere.
‘ perché non dichiarare FileWriter, FileReader, BufferedReader e BufferedWriter in cima alla classe come hanno fatto per le altre variabili?’
Ok, presumo che tu capisca che le variabili non sono effettivamente chiamate FileWriter
, FileReader
, BufferedReader
, e BufferedWriter
, ma piuttosto questo è il tipo di variabile. I loro nomi sono fw
, fr
, br
, e bw
. Se non capisci cosa intendo, chiedi. D’ora in poi mi riferirò alle variabili con i nomi che hai fatto per rendere la lettura più facile, dopotutto fw
sta solo per FileWriter
comunque, quindi non dovrebbe esserci troppa confusione.
La chiave di questa domanda è nascosta nei nomi delle variabili stesse. Nota come finiscono in Reader
o Writer
questo può darci un sottile indizio sui loro usi. Chiaramente FileWriter
e BufferedWriter
hanno a che fare con l’output in qualche modo. Esaminando il codice vediamo che i nostri sospetti avevano ragione e che in nessun punto diverso dal metodo writeText(JTextArea area)
appaiono queste variabili. Quindi, se la variabile non viene utilizzata da nessun’altra parte all’interno del codice, avrebbe senso logico definirle e inizializzarle all’interno del metodo in cui sono utilizzate, non solo rende il codice più facile da leggere perché quindi “sappiamo” che quelle variabili sono correlate solo a quel metodo, ma ha anche il vantaggio di rimuovere quelle variabili alla fine dell’esecuzione del metodo, quindi non lasciando variabili esistenti che sono state usate solo molto brevemente. Con queste regole possiamo dire lo stesso vale per FileReader
e BufferedReader
.
Osservare questo esempio sull’ambito variabile. (Guarda i commenti che ho aggiunto al codice)
public class DataBase {private static String buf, retString = "\n"; // buf & retString - createdprivate static File file = new File("test.txt"); // file - createdpublic static void readText(JTextArea area) { try { FileReader fr = new FileReader (file); // fr (FileReader) - created BufferedReader br = new BufferedReader(fr); // br (BufferedReader) - created while ((buf = br.readLine()) != null) { area.append(buf); area.append(retString); } br.close(); fr.close(); } // fr (FileReader & br (BufferedReader) - destroyed catch (IOException e) { System.out.println("Exception: " + e); }}public static void writeText(JTextArea area) { try { FileWriter fw = new FileWriter (file); // fw (FileWriter) - created BufferedWriter bw = new BufferedWriter(fw); // bw (BufferedWriter) - created bw.write(area.getText()); bw.close(); fw.close(); } // fw & bw - destroyed catch (IOException e) { System.out.println("Exception: " + e); }}} // buf, retString and file - Still exist as long as the object exists
Da questo esempio diventa più chiaro il motivo per cui le variabili sono definite nei metodi piuttosto che come variabili di istanza e inizializzate all’interno del costruttore. Consente un codice molto più pulito oltre ad essere più readabe.
Perché farlo ogni volta che viene chiamato il metodo piuttosto che usare forse la stessa variabile di istanza?
Bene questa domanda ha a che fare con i tipi di variabili. Non è stato possibile riutilizzare una singola variabile per tutte le informazioni in quanto i tipi avrebbero dovuto essere diversi.
Se prendiamo tutte le variabili dal codice
private static String buf, retString = "\n"; // validprivate static File file = new File("test.txt"); // validFileReader fr = new FileReader (file); // validBufferedReader br = new BufferedReader(fr); // validFileWriter fw = new FileWriter (file); // validBufferedWriter bw = new BufferedWriter(fw); // valid
Ora sappiamo che non possiamo inserire un valore che non è dello stesso tipo della variabile in quella variabile, quindi qualcosa come
FileReader fr = new BufferedReader(fr); // Is not valid!
Perché i tipi semplicemente non corrispondono.
Ha senso?