Указатели закрыты в конце локальной декларации? - PullRequest
0 голосов
/ 03 мая 2020

У меня есть функция, и локально у меня есть несколько указателей для обработки файлов, чтения zip-файлов (используя java.util.zip.ZipFile), потоков и т. Д. c. Я должен заключить всю эту работу в оператор try{...}catch(...){...}, но когда это не удается, я должен закрыть все открытые указатели один за другим в соответствии с типом ошибки. Можно ли избежать этого, просто завершив функцию с помощью возврата?

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

Я искал информацию, но многого не достиг. Кто-нибудь знает больше об этой топи c?

1 Ответ

1 голос
/ 03 мая 2020

Закрыты ли указатели в конце локальной декларации?

Терминология: Java не имеет указателей. Они называются ссылками .

Краткий ответ: Нет.

Я должен заключить всю эту работу в оператор try{...}catch(...){...}, но когда это не удается, я должен закройте все открытые указатели один за другим в соответствии с типом ошибки.

Частично исправлено. Вы не должны закрывать ресурсы в catch блоках. Существует лучший способ. На самом деле есть два способа использования try для достижения того, что вы пытаетесь сделать.

До Java 7 вы могли бы сделать это:

SomeHandle h;
try {
    h = /* open it */
    ...
} catch (...) {
    ...
} finally {
    // close the resources
    if (h != null) {
       h.close();
    }
}

С Java 7 и далее вы можете написать это более просто, используя try with resources синтаксис:

try (Handle h = /* open it */)   // <<-- resource declarations
{
    ...
} catch (...) {
    ...
}

Ресурсы закрываются автоматически в обратном порядке, в котором они были объявлены. try-with-resources также заботится об исключениях, возникающих при закрытии ... но я сбиваюсь с пути. (Прочитайте учебное пособие по , попробуйте ресурсы , чтобы узнать все подробности.)

Можно ли избежать этого, просто завершив функцию через возврат?

Нет. Закрываемые ресурсы не закрываются просто с помощью return.

Указатели объявляются локально внутри функции, поэтому я думаю, что они должны быть уничтожены в конце функции, как любая объявленная переменная, но будучи указателями они используют зарезервированное пространство памяти, ...

Это неверно в ряде аспектов:

  • Это ссылки, а не указатели.
  • Переменные объявляются, а не ссылки. Ссылки создаются выражением new.
  • Ссылки относятся к строго типизированным объектам в куче. (Не «пространство памяти». Java не может напрямую обращаться к памяти.)
  • Переменные не «уничтожаются» в Java. Они просто перестают быть доступными, когда они go выходят за рамки. (Это не «просто семантика». Дело в том, что абсолютно никакой код «уничтожения» не выполняется, когда переменная выходит из области видимости. Даже присвоение переменной null.)
* 1060 Короче говоря, то, что вы думаете, происходит с Java локальными переменными, на самом деле не происходит. Java в этом отношении принципиально отличается от C ++.

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

Фактически, ничего не происходит с объектом кучи, когда переменная, содержащая ссылку, выходит из области видимости.

Объект кучи остается там до тех пор, пока сборщик мусора (в конце концов!) Не обнаружит, что объект больше не достижим . Затем (и только тогда) он удалит объект.

Для большинства объектов это не проблема.

Для объектов, которые содержат дескрипторы для внешних ресурсов, которые должны быть освобождены (например, файловые дескрипторы , отображенные в память файлы и т. д. c) это проблема. Вот почему такими объектами нужно управлять более напрямую ... с помощью явного вызова close или с помощью try с ресурсами .

(Обратите внимание, что объекты, которые содержат дескрипторы для внешних ресурсов обычно имеет какой-то механизм финализации, который закрывает ресурсы. Проблема в том, что этого не произойдет до окончания сборки мусора ... и это может быть слишком поздно.)

...