Недостатки Java попробовать с ресурсами - PullRequest
0 голосов
/ 10 марта 2020

У меня есть метод, который загружает файл в ридер. Тесты или другой код могут использовать этот ридер для чтения файла. Проблема в том, что я не могу объявить читателя вне блока try-with-resources / TWR. Является ли это недостатком TWR или я что-то упускаю?

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class TestngTesting {
    BufferedReader fileReader;//Can't declare this as final, because its not assigned here itself.
    BufferedReader fileReader1;

    //Can be made @BeforeClass method.
    public void loadFile() throws IOException {
        fileReader = new BufferedReader(new FileReader("path/file.txt"));

        //Compile error - Variable used as a try-with-resources resource should be final or effectively final.
        try(fileReader){

        }

        try{
            fileReader1 = new BufferedReader(new FileReader("path/file.txt"));
        }finally {
            //end gracefully.
        }
    }
}

PS - я прочитал эти два поста, прежде чем опубликовать свой вопрос - ссылка , ссылка .

Ответы [ 3 ]

1 голос
/ 10 марта 2020

Это не так.

Если вы хотите безопасно работать с ресурсами, вам нужно определить некоторую лексическую область, в которой ресурс является действительным, и в любое время код переходит за пределы этой области, он недопустим.

Неспособность сделать это означает, что ни компилятор, ни какой-либо инструмент для рисования не могут отследить, правильно ли вы это делаете, поэтому теперь это ошибка, и ошибки трудно обнаружить. Если вы действительно этого хотите, круто - но ARM уже прав, смысл ARM в том, чтобы упростить задачу лексического ограничения.

Если вы не можете найти способ использовать попытку с блоком ресурсов (ARM), чтобы сделать это, тогда у вас нет ситуации лексического контекста Однако это не означает, что вы немедленно обречены на старый небезопасный способ sh.

Вы можете иметь поле, содержащее ресурс без потери ARM .

Но это означает, что объект с этим полем сам должен стать AutoClosable - вы можете перенести бремя пробного поиска ресурсов в другое место на код, который вызывает ваш код, использующий ресурсы. Затем все, что вам нужно сделать, - это закрыть этот ресурс в вашем собственном методе close (), который является единственным методом, который вам нужно реализовать, если вы implements AutoClosable (это позволяет другому коду пробовать экземпляры вашего класса).

Конечно, если все, что вам нужно, это сдвинуть объявление без особой разумной причины, ARM действительно «кодирует» стиль кода, в котором вы объявляете переменную только тогда, когда вам это нужно, а не стиль, в котором вы объявляете все наверху.

Исходя из моего опыта и изучения различных руководств по стилю, «объявлять все локальные переменные вверху» необычно и имеет недостатки; объявления лексически ограничены. Это хорошо, и для чего-то вроде ARM, крайне важно. В конце концов, я не ХОЧУ трогать эту переменную, когда она уже закрыта, для подавляющего большинства ресурсов выполнение каких-либо действий с ними post-close () в любом случае является немедленным исключением.

0 голосов
/ 10 марта 2020

Вы можете переназначить его локальной переменной:

public class TestngTesting {
    BufferedReader fileReader;

    public void loadFile() throws IOException {
        fileReader = new BufferedReader(new FileReader("path/file.txt"));

        try (BufferedReader r = fileReader) {

        }
    }
}
0 голосов
/ 10 марта 2020

Проблема в том, что я не могу объявить читателя вне блока try-with-resources / TWR. Это недостаток TWR или я что-то упустил?

Вы всегда можете объявить и инициализировать это в блоке try-with-resources:

try(BufferedReader fileReader = new BufferedReader(new FileReader("path/file.txt"))){
      // Print each line
      String line;
      while ((line = fileReader.readLine()) != null) {
          System.out.println(line);
      }
} catch (IOException e) {
     System.err.format("IOException: %s%n", e);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...