Oui, si vous avez appelé myMethod()
10 fois, cela créera 10 objets uniques et séparés.
Le mot-clé new
fait exactement ce qu’il dit sur le tin, il crée un tout nouvel objet, qu’il en existe déjà un ou plusieurs. Il crée un nouvel objet et insère la référence à cet objet à l’intérieur de la variable qui lui a été donnée, écrasant toute valeur précédente (objet) que la variable détenait.
La variable myObject est-elle réaffectée à chaque fois ?
Encore une fois, oui, il serait réaffecté avec un nouvel objet à chaque appel de la méthode. Une note intéressante à ce sujet serait que la variable ne serait pas « vraiment » réallouée car vous définissez la variable dans le corps de la méthode elle-même, donc chaque fois que la méthode se termine, elle supprimera les variables qui ont été définies dans sa portée. Donc, ce qu’il fait réellement, c’est créer 10 variables individuelles et attribuer 10 objets individuels, bien que, comme je l’ai dit, les autres auraient dû être supprimés automatiquement afin de ne pas utiliser de mémoire supplémentaire.
En un mot: dois-je écrire du code comme ça uniquement si je prévois d’invoquer cette méthode une seule fois?
Eh bien, comme je l’ai dit, dans l’exemple ci-dessus, chaque objet serait détruit à la fin de l’exécution de la méthode (en supposant que vous n’ayez pas assigné la référence de l’objet à une variable en dehors de la portée de la méthode), donc dans votre exemple, vous pourriez volontiers appeler la méthode autant de fois que vous le souhaitez, mais chaque fois ne serait en aucun cas connecté aux appels précédents.
Je me rends compte que ma façon d’écrire peut être déroutante, alors si vous voulez que je clarifie quelque chose, demandez simplement.
‘pourquoi ne pas déclarer FileWriter, FileReader, BufferedReader et BufferedWriter en haut de la classe comme ils l’ont fait pour les autres variables?’
D’accord, je suppose que vous comprenez que les variables ne sont pas réellement appelées FileWriter
, FileReader
, BufferedReader
, et BufferedWriter
, mais c’est plutôt le type variable. Leurs noms sont fw
, fr
, br
, et bw
. Si vous ne comprenez pas ce que je veux dire, demandez simplement. À partir de maintenant, je me référerai aux variables par les noms que vous avez donnés pour faciliter la lecture, après tout fw
signifie juste FileWriter
de toute façon, donc il ne devrait pas y avoir trop de confusion.
La clé de cette question est cachée dans les noms des variables elles-mêmes. Remarquez comment ils se terminent par Reader
ou Writer
cela peut nous donner un indice subtil sur leurs utilisations. Il est clair que FileWriter
et BufferedWriter
sont liés à la sortie d’une manière ou d’une autre. En regardant le code, nous voyons que nos soupçons étaient justes et qu’à aucun moment autre que dans la méthode writeText(JTextArea area)
, ces variables n’apparaissent. Donc, si les variables ne sont utilisées nulle part ailleurs dans le code, il serait logique de les définir et de les initialiser dans la méthode dans laquelle elles sont utilisées, non seulement cela rend le code plus facile à lire car nous « savons » alors que ces variables ne sont liées qu’à cette méthode, mais a également l’avantage que ces variables soient supprimées à la fin de l’exécution de la méthode, ne laissant ainsi pas en existence des variables qui n’ont été utilisées que très brièvement. Par ces règles, nous pouvons dire la même chose pour FileReader
et BufferedReader
.
Observez cet exemple sur la portée variable. (Regardez les commentaires que j’ai ajoutés au code)
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
À partir de cet exemple, il devient plus clair pourquoi les variables sont définies dans les méthodes plutôt que comme des variables d’instance et initialisées dans le constructeur. Il permet un code beaucoup plus propre tout en étant plus lisible.
Pourquoi le faire chaque fois que la méthode est appelée plutôt que d’utiliser peut-être la même variable d’instance?
Eh bien, cette question concerne les types de variables. Nous ne pouvions pas réutiliser une seule variable pour toutes les informations car les types auraient dû être différents.
Si nous prenons toutes les variables du code
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
Maintenant, nous savons que nous ne pouvons pas placer une valeur qui n’est pas du même type que la variable dans cette variable, donc quelque chose comme
FileReader fr = new BufferedReader(fr); // Is not valid!
Parce que les types ne correspondent tout simplement pas.
Avoir du sens ?