Java одноразовый шаблон

#java #garbage-collection #dispose

#java #сбор мусора #утилизировать

Вопрос:

C # поддерживает одноразовый шаблон для детерминированной сборки мусора с использованием шаблона dispose .

Существует ли такой шаблон для Java?

В Java 7 есть autoclosable , который вы можете использовать с блоками try finally для вызова close метода.

Как насчет версий до 7?

Существует ли одноразовый шаблон (детерминированная сборка мусора) для Java 5 или 6?

Комментарии:

1. Боюсь, нет, вы должны сделать это вручную.

2. Автоматическое закрытие не влияет на сборку мусора. Что он делает, так это обеспечивает правильную очистку ресурсов. Вы уверены, что шаблон C # оказывает какое-либо влияние на GC?

3. Я просто хотел отметить, что ни C #, using ни Java 7 try с использованием шаблонов ресурсов не предлагают детерминированную сборку мусора . Они предлагают детерминированный контроль ресурсов . Я знаю, что я педантичен в этом, но это важное отличие.

4. @PeterLawrey похоже, что мы разместили одно и то же. C # такой же, как у Java; по умолчанию нет реального влияния на GC, хотя некоторые шаблоны (в частности, собственный шаблон, предложенный Microsoft) рекомендуют подавлять финализацию — первый шаг в сборке мусора. Несмотря на это, память объекта не восстанавливается немедленно.

Ответ №1:

Ближайший к Java 7 — это просто «ручные» блоки try / finally:

 FileInputStream input = new FileInputStream(...);
try {
  // Use input
} finally {
  input.close();
}
  

Это using утверждение было одной из самых приятных вещей, которые я нашел в C #, когда я впервые начал использовать C # 1.0 на фоне Java. Приятно наконец увидеть это в Java 7 🙂

Вы также должны учитывать Closeables в Guava — это позволяет вам не беспокоиться о том, является ли ссылка нулевой (точно так же, как using это делает оператор), и, возможно, «регистрирует и проглатывает» исключения, создаваемые при закрытии, чтобы избежать эффективного «перезаписывания» любого такого исключения исключением, генерируемым из блока try.

Комментарии:

1. Разве это не может привести к утечке ресурса? Не было бы лучше инициализировать input null снаружи try и построить FileInputStream внутри try . Затем finally проверьте наличие не null экземпляра и закройте его. (Я почти уверен, что его нужно инициализировать null вне try , потому что в противном случае назначение не может быть гарантировано.)

2. @NoelWidmer: если между назначением и вводом блока может возникнуть асинхронное исключение try , то такое же исключение, предположительно, может возникнуть после завершения конструктора, но до того, как результирующая ссылка будет присвоена input переменной. Но, по крайней мере, в Java я не считаю, что это проблема.

3. @JonSkeet Ты прав. (Хотя я не знаю, может ли асинхронность быть проблемой в Java)

4. @Noel: Под асинхронными исключениями я подразумеваю исключения, которые могут быть сгенерированы в совершенно произвольных точках.

5. @JonSkeet я знаю, что ты имел в виду. Эти мерзкие звери — причина, по которой я изначально прокомментировал.

Ответ №2:

Вся цель шаблона удаления — поддерживать уникальный using (temporaryObject) шаблон C #. У Java не было ничего подобного этому шаблону до 7.

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

Комментарии:

1. Я знаю, что это старый пост, но для полноты картины справедливо сказать, что все наоборот. Вся цель using состоит в том, чтобы гарантировать, что одноразовые объекты в локальном контексте действительно удаляются, не требуя вложения try / finally. Сам одноразовый шаблон часто используется вне локального контекста и, следовательно, без using него, особенно если удаляемый объект содержит ссылки на другие одноразовые объекты.

Ответ №3:

То, что вы ищете, — это попробовать с ресурсами.

 try ( FileInputStream input = new FileInputStream(...);
      BufferedReader br = new BufferedReader(...) ) {
  // Use input
} 
  

Конечно, ресурс должен быть закрываемым (или автоматически закрываемым).

Комментарии:

1. Из вопроса OPs ясно, что он уже знает об этом и что он спрашивает, как это можно было сделать до Java 7…