Да, если вы позвоните myMethod()
10 раз, он создаст 10 уникальных и отдельных объектов.
Ключевое слово new
делает именно то, что говорит на жестяной банке, оно создает новый объект, независимо от того, существует ли он уже. Он создает новый объект и вставляет ссылку на этот объект в указанную переменную, перезаписывая любое предыдущее значение (объект), содержащееся в переменной.
Перемещается ли переменная myObject каждый раз?
Опять же, да, он будет перераспределяться с новым объектом при каждом вызове метода. Интересно отметить, что переменная «на самом деле» не будет перераспределена, поскольку вы определяете переменную внутри самого тела метода, поэтому каждый раз, когда метод завершается, он удаляет переменные, которые были определены в его области видимости. , Так что на самом деле он создает 10 отдельных переменных и назначает 10 отдельных объектов, хотя, как я сказал, остальные должны были быть удалены автоматически, чтобы не использовать дополнительную память.
В двух словах: должен ли я писать такой код, только если я планирую вызывать этот метод только один раз?
Как я уже сказал, в приведенном выше примере каждый объект будет уничтожен в конце выполнения метода (при условии, что вы не присвоили ссылку на объект на переменную вне области действия метода), так что в вашем примере вы могли бы счастливо вызывайте метод столько раз, сколько вы хотите, но каждый раз никоим образом не будет связан с предыдущими вызовами.
Я понимаю, что мой способ письма может сбивать с толку, поэтому, если вы хотите, чтобы я что-то разъяснил, просто спросите.
Обновленный ответ для отражения отредактированного вопроса
'почему бы не объявить FileWriter, FileReader, BufferedReader и BufferedWriter в верхней части класса, как они делали для других переменных?'
Хорошо, я предполагаю, что вы понимаете, что переменные на самом деле не называются FileWriter
, FileReader
, BufferedReader
и BufferedWriter
, а скорее это тип переменной. Их имена fw
, fr
, br
и bw
. Если вы не понимаете, о чем я, просто спросите. Отныне я буду ссылаться на переменные по именам, которые вы делали, чтобы облегчить чтение, в конце концов fw
в любом случае означает FileWriter
, поэтому не должно быть слишком много путаницы.
Ключ к этому вопросу скрыт в именах самих переменных. Обратите внимание на то, как они заканчиваются на Reader
или Writer
, что может дать нам тонкую подсказку об их использовании. Ясно, что FileWriter
и BufferedWriter
каким-то образом связаны с выводом. Просматривая код, мы видим, что наши подозрения были верны и что ни в одной точке, кроме метода writeText(JTextArea area)
, эти переменные не появляются. Поэтому, если переменная не используется где-либо еще в коде, было бы логично определить и инициализировать их в методе, в котором они используются, и это не только облегчит чтение кода, поскольку мы затем «знаем» эти переменные относятся только к этому методу, но также имеет то преимущество, что эти переменные удаляются в конце выполнения метода, тем самым не оставляя существующие переменные, которые использовались очень кратко. По этим правилам мы можем сказать, что то же самое верно для FileReader
и BufferedReader
.
Обратите внимание на этот пример с областью действия переменной. (Посмотрите на комментарии, которые я добавил к коду)
public class DataBase {
private static String buf, retString = "\n"; // buf & retString - created
private static File file = new File("test.txt"); // file - created
public 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
Из этого примера становится более понятным, почему переменные определяются в методах, а не в качестве переменных экземпляра и инициализируются в конструкторе. Это позволяет намного более чистый код, а также быть более читабельным.
Зачем делать это каждый раз, когда вызывается метод, а не использовать, возможно, одну и ту же переменную экземпляра?
Ну, этот вопрос касается типов переменных. Мы не могли повторно использовать одну переменную для всей информации, поскольку типы должны были бы быть разными.
Если мы возьмем все переменные из кода
private static String buf, retString = "\n"; // valid
private static File file = new File("test.txt"); // valid
FileReader fr = new FileReader (file); // valid
BufferedReader br = new BufferedReader(fr); // valid
FileWriter fw = new FileWriter (file); // valid
BufferedWriter bw = new BufferedWriter(fw); // valid
Теперь мы знаем, что мы не можем поместить значение, которое не относится к той же переменной, что и переменная, в эту переменную, например,
FileReader fr = new BufferedReader(fr); // Is not valid!
Потому что типы просто не совпадают.
Имеет смысл?