завел мой врач издалека.
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, Содержание. |
