Ревью исключения. 3 ревью Исключения. Что такое исключение Для чего они нужны
Скачать 236.75 Kb.
|
Что такое исключение? Для чего они нужны? Исключения в программировании (exceptions) — это механизм, который позволяет программе обрабатывать нетипичную ситуацию и при этом не прекращать работу. Благодаря этому механизму разработчик может описать в коде реакцию программы на такие ситуации. Механизм обработки исключений может понадобиться любому разработчику. Если не отслеживать исключительные ситуации, может возникнуть незаметная ошибка, которая нарушит работу всего кода, или программа может «зависнуть» либо «упасть» — потому что сложный момент не был обработан как надо. Исключения нужны, чтобы программа продолжала относительно корректно работать, даже если что-то пошло не так. Расскажи про иерархию исключений? В Java все исключения наследуются от класса Throwable, который является корневым классом иерархии исключений в Java. Класс Throwable имеет два основных подкласса: Error и Exception. Класс Error представляет ошибки, возникающие внутри виртуальной машины Java (JVM) и не подлежащие обработке. Некоторые из распространенных ошибок, наследующихся от класса Error, включают OutOfMemoryError (когда не хватает памяти для выполнения программы) и StackOverflowError (когда слишком много вызовов методов приводят к переполнению стека). Класс Exception представляет все исключения, которые могут возникнуть во время выполнения программы и которые можно обработать. Класс Exception имеет множество подклассов, таких как IOException (исключение, возникающее при работе с вводом-выводом), SQLException (исключение, возникающее при работе с базой данных), RuntimeException и многие другие. RuntimeException и его подклассы могут возникать во время выполнения программы и могут быть не обработаны, поэтому их обработка является дополнительной задачей для программиста. Ниже класса Exception располагаются классы RuntimeException и Error, которые наследуются от класса Throwable, но не являются подклассами класса Exception. Иерархия исключений в Java позволяет программистам более точно обрабатывать ошибки, возникающие во время выполнения программы. Более общие классы исключений, такие как Exception, могут быть использованы для обработки нескольких типов исключений, в то время как более конкретные классы исключений могут быть использованы для обработки более специфических ошибок. Создание исключения При исполнении программы исключение генерируется JVM или вручную, с помощью оператора throw. При этом в памяти создается объект исключения и выполнение основного кода программы прерывается, а обработчик исключений JVM пытается найти способ обработать исключение. Обработка исключения Создание блоков кода, для которых мы предусматриваем обработку исключений в Java, производится в программе с помощью конструкций try{}catch, try{}catch{}finally, try{}finally{}. При возбуждении исключения в блоке try обработчик исключения ищется в следующем за ним блоке catch. Если в catch есть обработчик данного типа исключения – управление переходит к нему. Если нет, то JVM ищет обработчик этого типа исключения в цепочке вызовов методов до тех пор, пока не будет найден подходящий catch. После выполнения блока catch управление передается в необязательный блок finally. В случае, если подходящий блок catch не найден, JVM останавливает выполнение программы, и выводит стек вызовов методов – stack trace, выполнив перед этим код блока finally при его наличии. В чём разница между проверяемыми исключениями и непроверяемыми? В чём разница с точки зрения синтаксиса и идеологическая при использовании? В Java существует два типа исключений: проверяемые (checked) и непроверяемые (unchecked) исключения. Проверяемые исключения - это исключения, которые должны быть обработаны или переданы в вызывающий метод. Компилятор Java требует, чтобы методы, которые могут сгенерировать проверяемое исключение, явно объявляли это в списке throws. Примерами проверяемых исключений являются FileNotFoundException и IOException. Непроверяемые исключения - это исключения, которые не обязательно должны быть обработаны или объявлены в списке throws. Эти исключения обычно свидетельствуют об ошибках в программе или невозможности продолжить выполнение программы. Примеры непроверяемых исключений: NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException. С точки зрения синтаксиса, проверяемые исключения должны быть обработаны в блоке try-catch или объявлены в списке throws метода, который может сгенерировать исключение. В случае с непроверяемыми исключениями блок try-catch или список throws не требуются. Идеологически, использование проверяемых исключений облегчает обнаружение и обработку исключений, поскольку они должны быть явно объявлены и обработаны. С другой стороны, использование непроверяемых исключений облегчает написание кода, поскольку нет необходимости обрабатывать их в каждом методе, который может их сгенерировать. Однако, это может привести к трудноотлавливаемым ошибкам в программе, поэтому непроверяемые исключения следует использовать осторожно и только тогда, когда это действительно оправдано. Можно ли обработать непроверяемое исключение? Да, непроверяемые исключения в Java можно обработать с помощью блока try-catch. Хотя для непроверяемых исключений блок try-catch не является обязательным, иногда может быть полезным обработать такие исключения внутри блока try-catch, чтобы убедиться, что программа не завершится аварийно. Если какой-то метод может выбросить непроверяемое исключение, мы можем заключить вызов этого метода в блок try-catch, чтобы обработать исключение в случае его возникновения. В этом случае, блок catch может содержать код, который исправляет ошибку или предупреждает пользователя об ошибке. Вот пример, который демонстрирует, как можно обработать непроверяемое исключение в блоке try-catch: try { int[ ] arr = {1, 2, 3}; System.out.println(arr[3]); // Вызовет ArrayIndexOutOfBoundsException } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Выход за пределы массива"); Здесь мы попытались обратиться к элементу массива, который не существует, и возникло исключение ArrayIndexOutOfBoundsException. Однако блок catch перехватил это исключение и вывел сообщение об ошибке вместо аварийного завершения программы. Нужно ли ловить Error исключения? В Java, классы Error и его подклассы, такие как OutOfMemoryError (приложение пытается выделить больше памяти, чем доступно в системе) и StackOverflowError (бесконечная рекурсия), предназначены для обозначения серьезных, неустранимых ошибок, которые обычно возникают в работающей программе и указывают на серьезные проблемы среды выполнения. В таких ситуациях приложение, как правило, не может справиться с этими ошибками и должно быть завершено. Обычно, обработка и ловля Error-исключений не рекомендуется, так как они обычно указывают на критические проблемы, которые нельзя исправить. Если ваша программа не может продолжать работу при возникновении Error, то вы не должны ловить их и попытаться обработать. Если вы все же хотите ловить и обрабатывать Error-исключения, то необходимо это делать с осторожностью и только в тех случаях, когда вы уверены, что можете предотвратить аварийное завершение программы. Например, вы можете обработать OutOfMemoryError, если вы знаете, что необходимо освободить память, прежде чем продолжить выполнение программы. Однако, в большинстве случаев, если возникает Error-исключение, то лучше позволить приложению завершиться, чтобы предотвратить еще большее ухудшение ситуации. Как бросить исключение? Можно ли бросить НЕ новое исключение? Да, в Java можно бросить не новое исключение. Это делается с помощью ключевого слова throw. Оно принимает любой экземпляр Throwable (или его производных) - это суперкласс для всех типов исключений. Например, следующая строка кода бросает некоторое уже существующее исключение: throw new IllegalArgumentException("Invalid argument"); Где возможно вызывать исключения? В любом месте кода с помощью throw new Exception();. Расскажи про информацию, которая находится внутри исключения? Как с ней работать? Информация, которая находится внутри исключения, может быть полезной для понимания того, что произошло во время выполнения программы, и помочь в отладке. В Java каждый класс исключения имеет ряд свойств (fields) и методов (methods), которые позволяют получить доступ к информации, содержащейся в исключении. Некоторые из наиболее распространенных свойств и методов: getMessage() - возвращает строку, которая описывает причину исключения; getCause() - возвращает объект Throwable, который был причиной этого исключения; getStackTrace() - возвращает массив объектов StackTraceElement, который представляет стек вызовов методов, когда исключение было брошено; toString() - возвращает строковое представление исключения, которое обычно включает имя класса исключения и его сообщение. Для получения доступа к этой информации, можно использовать ключевое слово "catch", чтобы перехватить исключение, и вызвать один из методов класса исключения. Например, в следующем коде сообщение об ошибке будет выведено на консоль: try { // код, который может бросить исключение } catch (Exception e) { System.out.println("Ошибка: " + e.getMessage()); } Можно получить более подробную информацию, например, стек вызовов методов, который привел к исключению, вы можете вызвать метод getStackTrace() объекта исключения. Например: try { // код, который может бросить исключение } catch (Exception e) { System.out.println("Ошибка: " + e.getMessage()); e.printStackTrace(); } Этот код выведет на консоль стек вызовов методов, который привел к исключению. Этот метод может быть очень полезен при отладке, но не должен использоваться в продакшен-коде, так как может предоставить злоумышленнику ценную информацию о структуре вашего приложения. Что такое подавленные исключения? Как достать подавленное исключение? Подавленное исключение (suppressed exception) - это исключение, которое было брошено в блоке "finally" после того, как уже было брошено первоначальное исключение. В Java 7 была добавлена новая функциональность, позволяющая сохранять подавленные исключения. Если в блоке "finally" возникает исключение, и в блоке try-catch также возникает исключение, то второе исключение становится подавленным. Это значит, что оно не будет брошено и будет добавлено к первоначальному исключению в качестве подавленного исключения. Чтобы достать подавленное исключение, можно использовать метод getSuppressed(), который возвращает массив всех подавленных исключений для данного объекта исключения. Например, в следующем коде мы создаем два исключения, одно из которых подавляется, а затем выводим на экран все подавленные исключения: public class SuppressedExceptionsExample { public static void main(String[] args) { try { throwException(); } catch (Exception e) { System.out.println("Первоначальное исключение: " + e.getMessage()); for (Throwable suppressed : e.getSuppressed()) { System.out.println("Подавленное исключение: " + suppressed.getMessage()); } } } public static void throwException() throws Exception { try { throw new Exception("Первое исключение"); } finally { throw new Exception("Второе исключение"); } Результат работы программы: Первоначальное исключение: Второе исключение Подавленное исключение: Первое исключение В данном примере первое исключение было брошено в блоке try, а второе исключение было брошено в блоке finally. Второе исключение подавлено и добавлено к первому исключению в качестве подавленного исключения. Метод getSuppressed() позволяет получить доступ к подавленному исключению и вывести его сообщение на экран. Какую информацию можно получить из StackTraceElement? Класс StackTraceElement представляет один элемент из трассировки стека вызовов (stack trace), который позволяет узнать информацию о месте, где было вызвано исключение. Каждый объект StackTraceElement содержит следующую информацию: имя класса, в котором произошло исключение (getClassName()); имя метода, в котором произошло исключение (getMethodName()); имя файла исходного кода, в котором произошло исключение (getFileName()); номер строки исходного кода, на которой произошло исключение (getLineNumber()). Кроме того, класс StackTraceElement имеет несколько методов, которые могут быть полезны при работе с трассировкой стека вызовов, например: equals(Object obj) - сравнивает текущий объект с указанным объектом на равенство; hashCode() - возвращает хэш-код объекта; toString() - возвращает строковое представление объекта в формате "ClassName.methodName(FileName:lineNumber)". Класс StackTraceElement обычно используется вместе с трассировкой стека вызовов исключения, чтобы определить место, где возникло исключение, и проанализировать причину ошибки. Расскажи про конструкцию try-catch-finally? Конструкция try-catch-finally - это один из способов обработки исключений в Java. Она позволяет попытаться выполнить определенный блок кода и в случае возникновения исключения обработать его в блоке catch. Кроме того, блок finally позволяет выполнить код независимо от того, было ли исключение или нет. Конструкция try-catch-finally имеет следующий синтаксис: Блок try содержит код, который может вызвать исключение. Если исключение произойдет, выполнение кода в блоке try прервется и управление передастся в блок catch, который соответствует типу возникшего исключения. Если блок catch не обнаружит соответствующий тип исключения, оно будет передано в следующий блок catch, если он присутствует. Блок finally содержит код, который нужно выполнить в любом случае, независимо от того, было ли исключение или нет. Например, этот блок может содержать код для закрытия открытых файлов или сетевых соединений. Пример использования конструкции try-catch-finally: В примере используется блок try для открытия файла и выполнения операций с ним. Если файл не найден или произойдет ошибка ввода-вывода, управление передастся в соответствующий блок catch. В блоке finally выполняется закрытие файла, чтобы гарантировать, что ресурсы освободятся независимо от того, было ли исключение или нет. Что такое try-with-resources? Как работает эта конструкция? Конструкция try-with-resources в Java представляет собой удобный способ автоматически закрывать ресурсы, такие как файлы или сетевые соединения, после завершения их использования. Эта конструкция была введена в Java 7. Конструкция try-with-resources позволяет определить один или несколько ресурсов в заголовке try, которые будут автоматически закрыты при выходе из блока try. Синтаксис try-with-resources выглядит следующим образом: try (ResourceType resource = new ResourceType()) { // Блок кода, в котором происходит использование ресурса } catch (Exception e) { // Обработка исключений } В этом коде ResourceType - это тип ресурса, который должен быть закрыт после использования. В заголовке try ресурс инициализируется с помощью оператора new. В блоке try происходит использование ресурса, а затем он автоматически закрывается при выходе из блока try. Кроме одного ресурса, можно использовать несколько ресурсов в блоке try-with-resources, разделяя их точкой с запятой, например: try (ResourceType resource1 = new ResourceType(); ResourceType resource2 = new ResourceType()) { // Блок кода, в котором происходит использование ресурсов } catch (Exception e) { // Обработка исключений } Ресурсы, используемые в блоке try-with-resources, должны быть реализованы с помощью интерфейса AutoCloseable. Интерфейс AutoCloseable определяет метод close(), который используется для закрытия ресурсов. Пример использования try-with-resources для чтения содержимого файла: try (BufferedReader reader = new BufferedReader(new FileReader("filename.txt"))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } catch (IOException e) { System.out.println("Ошибка чтения файла: " + e.getMessage()); } В этом примере создается экземпляр BufferedReader, который читает содержимое файла "filename.txt". Когда блок try завершается, BufferedReader автоматически закрывается, что гарантирует, что ресурс будет освобожден, даже если возникнет исключение. Расскажи, как правильно ловить исключения? Иерархия catch блоков Ловля и обработка исключений в Java выполняется с помощью блока try-catch. Блок try содержит код, который может выбросить исключение, а блок catch используется для обработки выброшенного исключения. Конструкция catch в Java имеет иерархическую структуру, которая позволяет обрабатывать исключения на разных уровнях иерархии. Каждый блок catch отлавливает определенный тип исключения или его подклассы, начиная с самых конкретных и заканчивая самыми общими. Если в блоке try выбрасывается исключение, Java ищет соответствующий блок catch, который может обработать это исключение. Если подходящий блок catch не найден, то исключение передается на уровень выше, где происходит его поиск. Если исключение не обрабатывается ни одним блоком catch, программа завершается с выводом сообщения об ошибке. пример использования блоков try-catch в Java: try { // some code that may throw an exception } catch (ExceptionType1 e) { // handle exception of type ExceptionType1 } catch (ExceptionType2 e) { // handle exception of type ExceptionType2 } catch (Exception e) { // handle exception of type Exception or any of its subclasses } finally { // code to be executed regardless of whether an exception was thrown or not } В этом примере блок try содержит код, который может выбросить исключение. Затем идут несколько блоков catch, каждый из которых обрабатывает исключения определенного типа или его подклассы. Последний блок catch обрабатывает исключения типа Exception или его подклассы, если ранее не было обработано более конкретных типов исключений. Блок finally используется для кода, который должен быть выполнен независимо от того, возникло исключение или нет. Например, это может быть код для освобождения ресурсов, таких как файлы или сетевые соединения. При ловле исключений в Java, важно следовать нескольким правилам: Не ловите исключения, которые вы не знаете, как обработать. Лучше передать исключение на уровень выше, где оно может быть обработано. Обрабатывайте исключения, которые вы знаете, как обработать. Это позволит избежать непредвиденного поведения программы. Не игнорируйте исключения Можно ли одном catch обработать несколько исключений? Да, в Java можно использовать один блок catch для обработки нескольких типов исключений. Для этого в блоке catch указываются все типы исключений, которые нужно обработать, перечисленные через вертикальную черту |. Например: try { // Код, который может бросать исключения } catch (IOException | SQLException e) { // Обработка исключения } В данном примере мы используем один блок catch для обработки исключений типа IOException и SQLException. Если возникнет любое из этих исключений, то будет выполнен код в блоке catch. Обратите внимание, что объект исключения e будет иметь тип IOException или SQLException, в зависимости от того, какое исключение было брошено. Также можно использовать несколько блоков catch для обработки разных типов исключений. В этом случае иерархия catch блоков должна быть от наиболее специфичных исключений к более общим, чтобы избежать конфликтов между блоками. Иерархия исключений? – Object – Throwable – Exception/Error – Exception (IOException/RunTimeException) --------------------------------------------------------------------------------------------------------------------- Чем отличаются исключения от обычных классов? • Все исключения наследуются от класса Throwable. • Дело в том, что исключение – класс все-таки выделенный. При создании Throwable существуют большие накладные расходы – заполнение стека вызова. Это достаточно длительная процедура. И потому создавать исключение просто так – себе дороже. Его нужно создавать только тогда, когда без него не обойтись, когда оно точно будет выброшено. Проще это делать сразу вместе с директивой throw. • А вот держать в классе исключения какую-то информацию, которая позволит его обработать – вполне допустимо. Передавать эту информацию лучше через конструктор. Все ключевые слова и всё что с ними связано? – Try/Catch/Fynally/Throw/throws try: блок try содержит код, который может возбуждать исключения. Если исключение возникает, управление передается соответствующему блоку catch. catch: блок catch перехватывает и обрабатывает исключение, возбужденное в блоке try. finally: блок finally содержит код, который будет выполнен в любом случае, независимо от того, возникло исключение или нет. Используется для освобождения ресурсов или выполнения других завершающих операций. throw: оператор throw используется для явного возбуждения исключения в программном коде. Можно использовать свой собственный класс исключения, наследованный от класса Exception или RuntimeException. Синтаксис: throw new ExceptionType("Сообщение об ошибке"); throws: ключевое слово throws указывает на исключения, которые могут быть возбуждены методом и переданы в вызывающий метод для обработки. Синтаксис: public void someMethod() throws ExceptionType { // код, который может возбуждать исключения Всё исключения и как генерировать различные виды исключений? – throw new (); Как создать, выбросить, поймать свое исключение? – создать свой класс и наследоваться от Exception/RunTimeException в зависимости от того, какую ошибку нужно обработать. Где возможно вызывать исключения? – в классе, методе, в любом блоке try-catch-finally Конструкция try-finally? - В конструкции Try-Finally, инструкция Finally гарантированно выполнится, абсолютно независимо оттого, что произойдет в предложении Try. Однако, предложение Finally фактически не обрабатывает никаких исключений Можно ли обрабатывать разные исключения в одном блоке catch? – можно через знак | (прямая черта) Обязателен ли блок finally? А catch? Когда будет выполнен finally? – конструкция может быть как try/catch так и try/finally (т.е. без catch или finally, но что-то одно обязательно должно быть). Finally будет выполнен всегда, за исключением редких случаев. Когда не будет выполнен finally(4 случая)? – Если упала JVM, Бесконечный цикл в JVM (в блоке try/catch). Была вызвана команда System.exit, Если это поток демон, все не-демон потоки завершились, то он завершится до finally Когда JVM (Java Virtual Machine) выходит из работы. В этом случае выполнение программы прерывается, и блок finally не выполняется. Когда происходит бесконтрольное завершение работы программы, например, при вызове метода System.exit(). В этом случае выполнение программы прерывается, и блок finally не выполняется. Когда в блоке finally возникает исключение или ошибка, которые не перехватываются. В этом случае выполнение блока finally прерывается, и исключение или ошибка передается дальше по стеку вызовов. Будет ли выполнен finally при Error? – да, при ошибке типа Error блок finally также будет выполнен Разница try catch и if Какой return вернется? Из try или finally? – если оператор return написан и в try и в finally, то выполнится return в finally Что если в конструкции try finally вылетело исключение сначала в try а потом в finally? Какое исключение вылетит? Что будет с другим? – в случае если исключение вылетело и в try и в finally, то вылетит то, исключение, которое случилось в finally (как и с оператором return). Другое исключение оно просто «проглотит», если не было блока catch. Расскажи про информацию, которая находится внутри исключения? Как с ней работать? – Исключение содержит в себе stacktrace(стектрейс вызовов), т.е. последовательность вызванных функций, а также номер строки, на которой возникла ошибка. Что возвращает getStackTrace()? – возвращает массив StackTraceElement[] в котором содержатся элементы трассировки стека Какое правило должно соблюдаться при использовании нескольких блоков catch (с одним try)?– от меньшего к большему. Первыми должны ловиться наименьшие в иерархии исключения. Иначе будут «недостижимые» исключения, которые никогда не будут выполнены программой. Какое правило должно соблюдаться при попытке поймать несколько исключений в одном catch? – если мы ловим несколько исключений, одно из которых является родителем другого, то мы должны оставить только родителя, иначе компилятор будет ругаться. Исключения прописываются через разделитель |. Переменная объекта ex (Exception ex) является final Зачем создавать свой класс и наследовать его от Exception? – для создания СОБСТВЕННЫХ проверяемых исключительных ситуаций, которые не предусмотрены JVM или компилятором и последующей обработки этих ситуаций Что такое ошибка, а что такое исключительная ситуация? – исключительная ситуация – ситуация которую мы можем предсказать и обработать. Ошибка возникает на уровне JVM и не может быть обработана программистом (закончилась память в компьютере или переполнен стек – и взять её неоткуда, поэтому и обрабатывать смысла нет) Что нужно делать программисту, если в коде происходит деление на ноль? – это ошибка кода, которую программист должен убрать. Или убрать деление на 0 или добавить проверочное условие. От каких классов Throwable и его подклассов нельзя наследоваться? – технически от класса Error наследоваться не принято, т.к. это ошибки JVM (серьезные ошибки, которые программист итак обработать не может) Какую информацию можно получить из StackTraceElement? – актуальную. информация о текущем состоянии «стека вызовов функций» Когда одна функция вызывает другую, Java-машина помещает в этот стек новый элемент StackTraceElement. Когда функция завершается этот элемент удаляется из стека. Можно ли так написать try { throw new Object(); }? – это будет ошибкой, т.к. Object не является исключением, хотя и является родителем Throwable. Вся работа с исключениями начинается с класса Throwable В чём разница между проверяемыми исключениями и непроверяемыми? В чём разница с точки зрения синтаксиса и идеологическая при использовании? – checked(проверяемые исключение) мы должны или обработать с помощью try/catch или пробросить дальше добавлением в сигнатуру throws. Непроверямые ни обрабатывать ни делать что-либо ещё не нужно. Можно ловить и checked и unchecked, но ловить unchecked не нужно. Обрабатывать нужно только checked исключения. Unchecked исключения RunTimeException это больше ошибка кода (программиста), которую нужно исправить Какое назначение класса Throwable? - Класс Throwable есть базовым для всех стандартных классов исключений Java. Этот класс предоставляет ряд методов, которые можно использовать или переопределять в собственных классах обработки исключений. Эти классы должны быть унаследованы от класса Exception, который унаследован от класса Throwable Методы класса Throwable? – getMessage(): Возвращает сообщение об ошибке или исключении, которое было передано в конструктор при создании объекта. getCause(): Возвращает исключение, которое стало причиной текущего исключения. printStackTrace(): Выводит на консоль полную трассу стека, которая содержит информацию о вызове методов до момента возникновения исключения. getStackTrace(): Возвращает массив объектов класса StackTraceElement, который содержит информацию о вызове методов до момента возникновения исключения. initCause(Throwable cause): Устанавливает исключение, которое стало причиной текущего исключения. fillInStackTrace(): Обновляет трассу стека исключения, чтобы она содержала информацию о вызове всех методов до момента вызова данного метода. getLocalizedMessage(): Возвращает локализованное сообщение об ошибке или исключении. Что происходит если не обработать исключение? - Если не было предпринято дополнительных действий, то поток, в котором было выброшено и не обработано исключение, остановится, и распечатает стектрейс в вывод System Что такое подавленные исключения? - Подавленные исключения -это дополнительные исключения, которые возникают в операторе try-with-resources ( введенном в Java 7 ) при закрытии ресурсов AutoCloseable. Поскольку при закрытии ресурсов AutoCloseable может возникнуть несколько исключений, дополнительные исключения присоединяются к основному исключению как подавленные исключения . Как достать подавленное исключение? - Вы можете получить подавленные исключения, вызвав метод Throwable.getSuppressed(Throwable e) из исключения, созданного блоком try. Что такое ресурс в конструкции try-with-resources? - любой объект, класс которого реализует интерфейс java.lang.AutoCloseable или java.io.Closable. Что если исключение вылетело сначала в try, а потом в close в конструкции try-with-recources? Какое исключение вылетит? Что будет с другим? - Если исключение будет выброшено в основном коде и в методе close(), то приоритетнее будет первое исключение, а второе исключение будет подавлено, но информация о нем сохранится (с помощью метода Throwable.addSuppressed(Throwable exception), который вызывается неявно Java компилятором Когда происходит закрытие ресурса в конструкции try-with-resources если в try возникло исключение: до перехода в catch или после того как catch отработает? – сначала вызывается метод close(), а потом уже обрабатывает исключение (catch); Чем отличается close от autoclosable? close и AutoCloseable - это два связанных понятия в Java, которые используются для управления ресурсами и освобождения памяти. close - это метод, который используется для явного освобождения ресурсов, занятых объектом, например, файлов, сокетов, баз данных и т.д. Объект, который реализует интерфейс Closeable, должен иметь метод close, чтобы программист мог явно освободить ресурсы, которые объект занимает, когда он больше не нужен. Метод close должен вызываться явно программистом, когда объект больше не нужен. AutoCloseable - это интерфейс, который используется для автоматического управления ресурсами. Он предоставляет единственный метод close(), который позволяет объекту автоматически освобождать ресурсы, когда объект больше не нужен. Это можно сделать с помощью конструкции try-with-resources. Объект, который реализует интерфейс AutoCloseable, будет автоматически закрыт при выходе из блока try. Таким образом, close и AutoCloseable предоставляют два разных подхода к управлению ресурсами. Метод close используется для явного освобождения ресурсов, тогда как интерфейс AutoCloseable позволяет автоматически управлять ресурсами с помощью конструкции try-with-resources. |