410013796724260
• Webmoney
R335386147728
Z369087728698
Вопросы по Java на собеседовании (3)
Вопросы и ответы для собеседование по Java, Содержание. 1. Понятие «Исключение»Исключение — это ошибка, возникающая во время выполнения программы. Причины возникновения исключения могут разные, например :
Исключение в Java является объектом. Поэтому они могут не только создаваться автоматически виртуальной машиной JVM при возникновении исключительной ситуации, но и порождаться самим разработчиком. 2. Операторы исключенийJava имеет пять ключевых операторов для определения блока исключений, перехвата и возбуждения исключений :
Общая структура «перехвата» исключительной ситуации выглядит следующим образом : try { // код программы, который может привести к ошибке } catch(Exception e ) { // код программы для обработки исключений } finally { // выполнение блока программы независимо от наличия исключения } 3. Оператор throwsОператор throws включается в сигнатуру метода с целью обозначения возожности возникновения исключительной ситуации с определенным типом. Использовать данный оператор следует в описании тех методов, которые могут возбуждать исключения, но сами их не обрабатывают. Таким образом, оператором throws метод предупреждает другие методы, вызывающие данный, что у него могут быть вызваны необработанные исключения, чтобы вызывающие методы могли защитить себя от этих исключений. public class TestThrow { static void method() throws IllegalAccessException { System.out.println("inside method"); // . . . throw new IllegalAccessException ("Exception in method"); } public static void main(String args[]) { try { method(); } catch(IllegalAccessException e) { System.out.println("Catch inside main : " + e.getMessage()); } } } 4. Блоки кода try/catch и try/finallyКаждый оператор try требует наличия либо catch, либо finally, либо сочетания catch и finally. Блок кода finally не является обязательным, и может отсутствовать при использовании try/catch. Оператором finally создаётся блок кода, который должен быть выполнен после завершения блока try/catch. Если необходимо гарантировано выполнить определенный участок кода, то используется finally. Связка try/finally позволяет обеспечить выполнение блока кода независимо от того, какие исключения были возбуждены и перехвачены, даже в тех случаях, когда в методе нет соответствующего возбужденному исключению раздела catch. Пример использования try/finally представлен здесь. 5. Может ли блок finally не выполняться?Код блока finally не будет исполнен, если в код программы включен предшествующий блоку finally системный выход. Следующий пример демонстрирует данную ситуацию. try { System.exit(0); } catch(Exception e) { System.err.println(e.getMessage()); } finally { // код блока } 6. Проверяемые и непроверяемые исключенияВсе исключения делятся на «проверяемые» (checked) и «непроверяемые» (unchecked). Данное свойство присуще базовому классу исключения Throwable и передается по наследству (Error, Exception, RuntimeException). В исходном коде класса исключения данное свойство недоступно. Ниже представлена иерархия классов исключений. Object | Throwable(CHECKED) / \ Error(UNCHECKED) Exception(CHECKED) | RuntimeException(UNCHECKED) Исключения Throwable и Exception, а также все их наследники, за исключением Error и RuntimeException, являются «проверяемыми» checked исключениями. Error и RuntimeException, а также все их наследники, относятся к «непроверяемым» unchecked исключениям. Проверка исключения на checked выполняется компилятором (compile-time checking). Непроверяемые исключения можно перехватить (catch) в момент исполнения программы (runtime checking). Java – это язык программирования со статической типизацией, т.е. его компилятор отслеживает корректности использования типов : наличие полей и методов, checked исключения, и т.д. Следующий пример демонстрирует наличие двух ошибок программирования, определенные на этапе копиляции. public class TestException { public static Double divide(int i1, int i2) throws Exception { if (i2 != 0) return new Double (i2 / i2); else { Throwable e = new Exception(); throw e; // Unhandled exception type Throwable } } public static void main(String[] args) { Object obj = "Hello!"; char c = obj.charAt(0); // The method charAt(int) is // undefined for the type Object } } Сигнатура метода divide (операция деления) включает определение возможного исключения типа Exception, наследуемого от Throwable. Если делитель (i2) равен 0, то создается объект исключения типа Throwable и возбуждается исключение (throw t), которое не пропускает компилятор, т.к. тип возбуждаемого исключения не соответствует типу исключения в сигнатуре метода. Если в сигнатуре метода определить исключение типа Throwable, то ошибки не будет. В методе main определен объект obj с инициализацией определенным значением. В следующей строке компилятор находит ошибку, связанную с отсутствием метода charAt(int) в объекте типа Object. Если выполнить приведение типа obj к String, то компилятор пропустит код : char c = ((String)ref).charAt(0). Пример unchecked исключения представлен здесь. 7. Возбуждение исключенияКак было отмечено выше, исключение является объектом, который можно создать программно. Чтобы возбудить (выбросить) исключение используется оператор throw. Exception e = new SQLException(); throw e; 8. Определение исключения в сигнатуре методаВ сигнатуре метода можно определить возможное проверяемое (checked) исключение. Следующий пример демонстрирует определение исключения в сигнатуре метода f1() и его перехват в конструкторе класса. import java.io.EOFException; import java.io.FileNotFoundException; public class TestException { public TestException() { try { f1(); } catch (FileNotFoundException e) { e.printStackTrace(); } } public void f1() throws FileNotFoundException { throw new FileNotFoundException(); } public static void main(String[] args) { new TestException (); } } 9. Особенность RuntimeExceptionИсключение RuntimeException расширяет свойства Exception и является базовым классом для ошибок во время выполнения приложения. Данное исключение относится к необрабатываемым исключениям (unchecked). Согласно описанию класса это исключение может возникнуть во время нормальной работы JVM. Следующий код демонстрирует пример использования непроверяемого исключения NumberFormatException (наследующего свойства RuntimeException). В функции parseInt при преобразовании строкового значения в число в режиме run-time может возникнуть исключение. Можно метод функции Integer.parseInt() «обернуть» в try/catch, а можно передать обработку исключения функции в вызывающий метод, для чего в сигнатуре определяется соответствующее исключение (throws). public int parseInt(String s) throws NumberFormatException { return Integer.parseInt(s); } 10. Возбуждение исключения в методе mainЕсли в методе main возбудить исключение, то оно будет передано в виртуальную машину Java (JVM). 11. Множественные исключенияВ сигнатуре метода можно определить несколько возможных исключений. Для этого используется оператор throws и исключения, разделенные запятыми. Следующий пример демонстрирует метод callMethods с множественными возможными исключениями : import java.io.EOFException; import java.io.FileNotFoundException; public class TestException { public void callMethods() throws EOFException, FileNotFoundException { if (f1()) f0(); } public void f0() throws EOFException { // ... throw new EOFException(); } public boolean f1() throws FileNotFoundException { // ... throw new FileNotFoundException(); } } Чтобы перехватить несколько возможных исключений можно искользовать конструкцию try с несколькими catch. try { if (f1()) f0(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (EOFException e) { e.printStackTrace(); } 12. Последовательность нескольких блоков catchПри определение нескольких блоков catch следует руководствоваться правилом обработки исключений от «младшего» к старшему. Т.е. нельзя размещать первым блоком catch (Exception e) {...}, поскольку все остальные блоки catch() уже не смогут перехватить исключение. Помните, что Exception является базовым классом, поэтому его стоит размещать последним. Рассмотрим следующую иерархию наследования исключений : java.lang.Object java.lang.Throwable java.lang.Exception java.io.IOException java.io.EOFException Cамым младшим исключением является EOFException, поэтому он должен располагаться перед IOException и Exception, если используется несколько блоков catch с данными типами исключений. Следующий код является демонстрацией данного принципа. String x = "Hello"; try { if (!x.equals("Hello")) throw new IOException(); else throw new EOFException(); } catch (EOFException e) { System.err.println("EOFException : " + e.getMessage()); } catch (IOException e) { System.err.println("IOException : " + e.getMessage()); } catch (Exception e) { System.err.println("Exception : " + e.getMessage()); } 13. Поглащение исключений в блоке try...finallyЕсли было вызвано два исключения — одно в блоке try, а второе в finally — то, при отсутствии catch, исключение в finally «проглотит» предыдущее исключение. Следует блоки с возможными исключениями всегда обрамлять операторами try/catch, чтобы не потерять важную информацию. Следующий пример демонстрирует «поглащение» исключения в блоке try новым исключением в блоке finally. public class TestException { public TestException() { try { System.out.println(absorbingEx()); } catch (EOFException e) { System.out.println(e.getMessage()); } catch (IOException e) { System.out.println(e.getMessage()); } } public String absorbingEx() throws IOException, EOFException { try { throw new EOFException("EOFException"); // } catch (EOFException e) { // System.out.println("catch " + e.getMessage()); } finally { throw new IOException("finally IOException"); } } public static void main(String[] args) { new TestException(); System.exit(0); } } В результате в консоль будет выведено следующее сообщение : finally IOException Чтобы не «потерять» исключение, необходимо его корректно перехватить и обработать. В примере следует убрать комментарий с блока catch. 14. Исключение SQLExceptionИсключение SQLException связано с ошибками при работе с базой данных. Данное исключением относится к checked исключениям, и, следовательно, проверяется на этапе компиляции. java.lang.Object java.lang.Throwable java.lang.Exception java.sql.SQLException Споры вокруг SQLException связаны с тем, что исключение возникает во время исполнения, а обрабатывать его приходится в коде, чтобы не ругался компилятор; может быть следовало бы отнести его к unchecked run-time исключениям? Убедительный довод разработчиков данного исключения связан с тем, что необходимо программисту обработать свои возможные ошибки при работе с базой данных. 15. Ошибка ErrorОшибка Error относится к подклассу не проверяемых (unchecked) исключений, которая показывает серьезные проблемы, возникающие во время выполнения программы. Большинство из ошибок данного класса сигнализируют о ненормальном ходе выполнения программы, т.е. о возникновении критических проблем. Согласно спецификации Java, не следует пытаться обрабатывать Error в собственной программе, поскольку они связаны с проблемами уровня JVM. Исключения такого рода возникают, если, например, закончилась память, доступная виртуальной машине. 16. Обобщение исключенийПри определении в сигнатуре метода возможных исключений можно вместо нескольких проверяемых исключений указать общее (базовое) java.lang.Throwable. В этом случае, компилятор «пропустит код» и программа возможно отработает без сбоев. Например : public void callCommonException() throws Exception { Object obj = new Object(); method(obj); } public void method(Object obj) throws NumberFormatException, IllegalArgumentException { // ... } Использование Exception или Throwable в сигнатуре метода делает почти невозможным правильное обращение с исключениями при вызове метода. Вызывающий метод получает только информацию о том, что что-то может отработать некорректно. Перехват обобщенных исключений не позволяет «решить» проблему, т.е. «вылечить» программу, а помогает только обойти периодически возникающую проблему. Это может привести к нескольким непредвиденным ошибкам в других местах приложения. 17. Логирование исключенийЛучше всего логировать (регистрировать) исключение в месте его обработки. Это связано с тем, что именно в данном месте кода достаточно информации для описания возникшей проблемы. Кроме этого, одно и то же исключение при вызове одного и того же метода можно перехватывать в разных местах программы; регистрировать же следует в одном месте. Иногда исключение может быть частью ожидаемого поведения. В этом случае нет необходимости его регистрировать.
Вопросы и ответы для собеседование по Java, Содержание. |