Вопросы 151-160 для опытных разработчиков
Ответ: Fail-Fast и Fail-Safe - это два типа итераторов в Java коллекциях. Они отличаются в том, как ведут себя при модификации коллекции во время итерации.
Выбрасывает ConcurrentModificationException если коллекция модифицируется после создания итератора (кроме вызова remove() самого итератора).
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
Iterator<Integer> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
Integer key = iterator.next();
// Выбросит ConcurrentModificationException
if (key == 1) {
map.remove(1);
}
}
Работает с копией (снимком) коллекции вместо оригинала. Модификации не влияют на итерацию.
ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
map.put(1, "one");
map.put(2, "two");
Iterator<Integer> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
Integer key = iterator.next();
// Не выбросит исключение
if (key == 1) {
map.remove(1);
}
}
Ответ: Exception Handling - это механизм в Java для обработки ошибок и непредвиденных ситуаций, которые прерывают нормальный ход выполнения программы.
| Блок | Назначение |
|---|---|
try |
Содержит код, который может выбросить исключение |
catch |
Обрабатывает конкретное исключение |
finally |
Выполняется всегда, используется для очистки ресурсов |
throw |
Явно выбрасывает исключение |
throws |
Объявляет, что метод может выбросить исключение |
try {
// Код который может выбросить исключение
int result = 10 / 0;
} catch (ArithmeticException e) {
// Обработка исключения
System.out.println("Ошибка: " + e.getMessage());
} finally {
// Выполняется всегда
System.out.println("Очистка ресурсов");
}
Ответ: Существует два основных типа исключений в Java:
Встроенные исключения предоставляются библиотеками Java и делятся на две категории:
Пользовательские исключения определяются программистами для обработки специфических ситуаций, не покрытых встроенными исключениями. Создаются расширением подходящего класса исключения:
// Пользовательское исключение
class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message);
}
}
// Использование
try {
int age = 10;
if (age < 18) {
throw new InvalidAgeException("Возраст должен быть >= 18");
}
} catch (InvalidAgeException e) {
System.out.println(e.getMessage());
}
Ответ: Error и Exception - это два разных типа проблем в Java, но они часто путаются:
| Характеристика | Error | Exception |
|---|---|---|
| Восстановление | Невозможно восстановиться | Можно восстановиться |
| Тип проверки | Все unchecked (непроверяемые) | Checked и Unchecked |
| Причина | Проблема в окружении (JVM) | Проблема в программе |
| Время возникновения | Compile time и Runtime | Runtime (в основном) |
| Пакет | java.lang.Error | java.lang.Exception |
| Примеры | StackOverflowError, OutOfMemoryError, VirtualMachineError | NullPointerException, IOException, SQLException |
StackOverflowError - переполнение стека (бесконечная рекурсия)OutOfMemoryError - недостаточно памятиVirtualMachineError - ошибка JVMLinkageError - ошибка связывания классовNullPointerException - обращение к nullIOException - ошибка ввода/выводаSQLException - ошибка базы данныхFileNotFoundException - файл не найденError: Не обрабатывайте Error в вашем коде. Это системные ошибки, которые указывают на критические проблемы в JVM или окружении.
Exception: Обрабатывайте исключения в своем коде с помощью try-catch или throws.
Ответ: Иерархия исключений Java - это структура классов, которая организует все исключения и ошибки под классом Throwable. Она помогает Java классифицировать и обрабатывать различные типы проблем во время выполнения эффективно.
Object
↓
Throwable
↙ ↘
Error ← Unchecked Exception
↙ ↘
RuntimeException ← Unchecked Other Exceptions ← Checked
| Тип | Описание | Примеры |
|---|---|---|
| Error (Unchecked) | Системные ошибки JVM, не подлежат обработке | StackOverflowError, OutOfMemoryError |
| Checked Exception | Исключения, которые должны быть обработаны или объявлены (throws) | IOException, FileNotFoundException, SQLException |
| Unchecked Exception (RuntimeException) | Исключения, которые могут быть обработаны или нет | NullPointerException, ArrayIndexOutOfBoundsException |
// Checked Exception - должен быть обработан
try {
FileInputStream fis = new FileInputStream("file.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// Unchecked Exception - может быть обработан или нет
try {
int[] arr = new int[5];
System.out.println(arr[10]); // ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Index out of bounds");
}
// Error - не обрабатывается
// StackOverflowError произойдет при бесконечной рекурсии
Ответ: Runtime Exceptions - это исключения, которые возникают во время выполнения программы и не проверяются компилятором. Они обычно результат ошибок программирования или неправильной логики.
| Исключение | Описание | Пример |
|---|---|---|
NullPointerException |
Обращение к методу/полю null объекта | String s = null; s.length(); |
ArithmeticException |
Математическая ошибка (деление на 0) | int x = 10 / 0; |
ArrayIndexOutOfBoundsException |
Обращение к элементу за пределами массива | int[] arr = {1, 2}; arr[5]; |
ClassCastException |
Неправильное приведение типов | Object obj = "text"; Integer i = (Integer) obj; |
IllegalArgumentException |
Недопустимый аргумент метода | Thread.sleep(-100); |
// RuntimeException - не требует обработки, но может быть обработано
public class RuntimeExceptionExample {
public static void main(String[] args) {
// NullPointerException
try {
String str = null;
System.out.println(str.length()); // Выбросит NPE
} catch (NullPointerException e) {
System.out.println("NullPointerException caught!");
}
// ArithmeticException
try {
int result = 10 / 0; // Выбросит ArithmeticException
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero!");
}
// ArrayIndexOutOfBoundsException
try {
int[] arr = {1, 2, 3};
System.out.println(arr[10]); // Выбросит ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Array index out of bounds!");
}
}
}
Ответ: NullPointerException - это тип runtime исключения, которое выбрасывается, когда программа пытается использовать ссылку на объект, которая имеет значение null.
Основное назначение NullPointerException - указать, что никакое значение не присвоено переменной ссылки. Также оно используется для реализации структур данных, таких как связные списки и деревья.
// Пример 1: Обращение к методу null объекта
String str = null;
System.out.println(str.length()); // NullPointerException
// Пример 2: Обращение к полю null объекта
class Person {
public String name;
}
Person person = null;
System.out.println(person.name); // NullPointerException
// Пример 3: Синхронизация на null объекте
Object obj = null;
synchronized(obj) { // NullPointerException
// код
}
// Пример 4: Throw null исключения
try {
throw null; // NullPointerException
} catch (Exception e) {
e.printStackTrace();
}
// 1. Проверка перед использованием
String str = null;
if (str != null) {
System.out.println(str.length());
}
// 2. Использование Optional (Java 8+)
Optional<String> optional = Optional.ofNullable(str);
optional.ifPresent(s -> System.out.println(s.length()));
// 3. Инициализация значением по умолчанию
String str = "default";
// 4. Использование Objects.requireNonNull()
import java.util.Objects;
String str = Objects.requireNonNull(inputStr, "String cannot be null");
Ответ: ArrayStoreException выбрасывается, когда предпринимается попытка сохранить неправильный тип объекта в массиве объектов.
| Ситуация | Описание |
|---|---|
| Массив Double[] и попытка добавить Integer | Integer не совместим с Double, выбросит ArrayStoreException |
| Массив String[] и попытка добавить Integer | Integer не совместим с String, выбросит ArrayStoreException |
| Массив Number[] и попытка добавить String | String не является подклассом Number, выбросит ArrayStoreException |
// Java программа для демонстрации ArrayStoreException
public class GFG {
public static void main(String args[])
{
// Поскольку Double класс расширяет Number класс
// только значения типа Double
// могут быть сохранены в этом массиве
Number[] a = new Double[2];
// Попытка сохранить значение Integer
// в этом массиве типа Double
try {
a[0] = new Integer(4);
} catch (ArrayStoreException e) {
System.out.println("ArrayStoreException caught!");
System.out.println("Cannot store Integer in Double array");
}
}
}
ArrayStoreException caught!
Cannot store Integer in Double array
if (obj instanceof Double) { a[0] = (Double) obj; }List<Double> list = new ArrayList<>();Ответ: Checked и Unchecked Exceptions отличаются в том, как компилятор их обрабатывает. Checked исключения проверяются во время компиляции, а unchecked исключения возникают во время выполнения.
| Характеристика | Checked Exception | Unchecked Exception |
|---|---|---|
| Проверка | Проверяется компилятором (Compile-time) | Проверяется только во время выполнения (Runtime) |
| Обработка | Обязательно обработать или объявить с throws | Опционально обрабатывать |
| Иерархия | Наследуются от Exception (кроме RuntimeException) | Наследуются от RuntimeException |
| Причина | Обычно внешние проблемы (файлы, сеть, БД) | Обычно ошибки программирования и неправильная логика |
| Примеры | IOException, FileNotFoundException, SQLException, ClassNotFoundException | NullPointerException, ArithmeticException, ArrayIndexOutOfBoundsException |
Checked Exceptions:
Unchecked Exceptions:
// Checked Exception - ОБЯЗАТЕЛЬНО обработать
import java.io.*;
public class CheckedExceptionExample {
public static void main(String[] args) {
// FileNotFoundException - это Checked Exception
// Компилятор требует обработки
try {
FileInputStream fis = new FileInputStream("file.txt");
} catch (FileNotFoundException e) {
System.out.println("File not found!");
e.printStackTrace();
}
}
// ИЛИ объявить в методе
public static void readFile() throws FileNotFoundException {
FileInputStream fis = new FileInputStream("file.txt");
}
}
// Unchecked Exception - ОПЦИОНАЛЬНО обработать
public class UncheckedExceptionExample {
public static void main(String[] args) {
// NullPointerException - это Unchecked Exception
// Компилятор НЕ требует обработки, но можно обработать
// Вариант 1: Без обработки (компилятор согласен)
String str = null;
// System.out.println(str.length()); // Выбросит NPE
// Вариант 2: С обработкой (опционально)
try {
System.out.println(str.length());
} catch (NullPointerException e) {
System.out.println("String is null!");
}
}
}
Checked Exception: Используйте когда код может выбросить исключение из-за внешних факторов, которые вне контроля программы.
Unchecked Exception: Используйте когда исключение результат ошибки в коде, которую можно предотвратить проверками.
Ответ: Базовым классом для Error и Exception является java.lang.Throwable.
Object
↓
Throwable
↙ ↘
Exceptions Error
├─ Checked Exceptions ├─ Virtual Machine Error
│ (IO, Compile time) ├─ Assertion Error
│
└─ Unchecked Exceptions
(Runtime, Null Pointer)
| Аспект | Error | Exception |
|---|---|---|
| Базовый класс | java.lang.Throwable |
|
| Тип | Системная ошибка JVM | Непредвиденное событие или условие |
| Восстановление | Невозможно восстановиться | Можно восстановиться |
| Обработка | Не обрабатывается | Обрабатывается или объявляется |
| Контроль | Вне контроля программы | В контроле программы |
| Примеры | StackOverflowError, OutOfMemoryError, VirtualMachineError | IOException, FileNotFoundException, NullPointerException |
java.lang.Throwable - это суперкласс всех ошибок и исключений в иерархии исключений Java. Он содержит общие методы для обработки исключений:
// Методы Throwable класса
public String getMessage() // Возвращает сообщение об ошибке
public void printStackTrace() // Выводит trace ошибки
public String toString() // Возвращает строковое представление
public Throwable getCause() // Возвращает причину исключения
public StackTraceElement[] getStackTrace() // Возвращает stack trace
public class ThrowableExample {
public static void main(String[] args) {
try {
// Может выбросить Exception
int result = 10 / 0;
} catch (Throwable t) { // Catching Throwable (родитель Exception)
System.out.println("Caught: " + t.getClass().getName());
t.printStackTrace();
System.out.println("Message: " + t.getMessage());
}
}
}
// Вывод:
// Caught: java.lang.ArithmeticException
// java.lang.ArithmeticException: / by zero
// Message: / by zero