Ссылочные типы в Java — интерфейсы (interfaces)
Интерфейсы в Java — это ключевой механизм для реализации абстракции, полиморфизма и разделения ответственности. Они относятся к ссылочным типам и позволяют описывать поведение, не определяя конкретную реализацию. Интерфейсы широко применяются при проектировании архитектуры, обеспечивают гибкость, модульность и поддержку паттернов проектирования.
Понимание интерфейсов необходимо для эффективного взаимодействия с фреймворками, библиотеками и построения легко расширяемого кода.
Создание интерфейсов
Интерфейсы объявляются с помощью ключевого слова interface. Они содержат объявления методов без реализации (до Java 8) или с ограниченной реализацией (начиная с Java 8):
Класс, реализующий интерфейс, должен предоставить реализацию всех его методов:
Начиная с Java 8, интерфейсы могут содержать:
default-методы с реализацией
static-методы
private-методы (с Java 9)
Ключевые особенности:
Интерфейс не может содержать поля с реализацией — только public static final константы.
Все методы по умолчанию public abstract, если не указано иное.
Интерфейс — это тип, и его можно использовать как ссылку.
Использование интерфейсов
Интерфейсы позволяют описывать поведение без привязки к конкретной реализации:
Это даёт возможность:
использовать полиморфизм,
отделять абстракции от реализаций,
писать гибкий и расширяемый код.
Интерфейсы можно использовать как:
параметры методов
типы переменных
результаты возвращаемых значений
обобщенные типы
Также интерфейсы — неотъемлемая часть функционального программирования в Java 8+:
Существование и удаление
Поскольку интерфейсы — это ссылочные типы, они работают как любые другие объекты. Переменная типа интерфейса — это ссылка на объект, реализующий этот интерфейс.
Здесь animal — это ссылка на объект типа Dog, но доступ к нему осуществляется через интерфейс Animal. Удаление объекта происходит по общим правилам: когда все ссылки исчезают, он становится доступным для сборки мусора.
Полиморфизм через интерфейсы
Интерфейсы — один из основных инструментов реализации полиморфизма. Код, написанный против интерфейсов, легко расширяем:
#Java #для_новичков #beginner #reference_types #Interface
Интерфейсы в Java — это ключевой механизм для реализации абстракции, полиморфизма и разделения ответственности. Они относятся к ссылочным типам и позволяют описывать поведение, не определяя конкретную реализацию. Интерфейсы широко применяются при проектировании архитектуры, обеспечивают гибкость, модульность и поддержку паттернов проектирования.
Понимание интерфейсов необходимо для эффективного взаимодействия с фреймворками, библиотеками и построения легко расширяемого кода.
Создание интерфейсов
Интерфейсы объявляются с помощью ключевого слова interface. Они содержат объявления методов без реализации (до Java 8) или с ограниченной реализацией (начиная с Java 8):
public interface Animal {
void makeSound();
}
Класс, реализующий интерфейс, должен предоставить реализацию всех его методов:
public class Dog implements Animal {
public void makeSound() {
System.out.println("Woof");
}
}
Начиная с Java 8, интерфейсы могут содержать:
default-методы с реализацией
static-методы
private-методы (с Java 9)
public interface Logger {
default void log(String msg) {
System.out.println("Log: " + msg);
}
}
Ключевые особенности:
Интерфейс не может содержать поля с реализацией — только public static final константы.
Все методы по умолчанию public abstract, если не указано иное.
Интерфейс — это тип, и его можно использовать как ссылку.
Использование интерфейсов
Интерфейсы позволяют описывать поведение без привязки к конкретной реализации:
public void processAnimal(Animal animal) {
animal.makeSound(); // работает с любым классом, реализующим Animal
}
Это даёт возможность:
использовать полиморфизм,
отделять абстракции от реализаций,
писать гибкий и расширяемый код.
Интерфейсы можно использовать как:
параметры методов
типы переменных
результаты возвращаемых значений
обобщенные типы
Также интерфейсы — неотъемлемая часть функционального программирования в Java 8+:
@FunctionalInterface
public interface Converter<F, T> {
T convert(F from);
}
Существование и удаление
Поскольку интерфейсы — это ссылочные типы, они работают как любые другие объекты. Переменная типа интерфейса — это ссылка на объект, реализующий этот интерфейс.
Animal animal = new Dog();
Здесь animal — это ссылка на объект типа Dog, но доступ к нему осуществляется через интерфейс Animal. Удаление объекта происходит по общим правилам: когда все ссылки исчезают, он становится доступным для сборки мусора.
Полиморфизм через интерфейсы
Интерфейсы — один из основных инструментов реализации полиморфизма. Код, написанный против интерфейсов, легко расширяем:
List<String> list = new ArrayList<>();
Map<String, Integer> map = new HashMap<>();
Здесь List и Map — интерфейсы, а ArrayList и HashMap — конкретные реализации. Это позволяет заменить реализацию без изменения остального кода.
#Java #для_новичков #beginner #reference_types #Interface
Множественное наследование
Классы в Java не могут наследовать более одного класса, но могут реализовать несколько интерфейсов:
Трудности и подводные камни
1. Конфликт default-методов
Если класс реализует несколько интерфейсов, в которых есть default-методы с одинаковыми сигнатурами, возникает конфликт:
2. Отсутствие состояния
Интерфейсы не могут содержать нестатические поля, что ограничивает их в сравнении с абстрактными классами. Всё, что можно объявить — это public static final константы.
3. Непредсказуемое поведение equals/hashCode
Если объект используется через интерфейс, его поведение equals() и hashCode() может зависеть от реализации, что важно при использовании в коллекциях.
4. Ошибки при переопределении
Ошибки в сигнатурах при реализации интерфейса не всегда очевидны. Например, случайное переопределение метода с другой сигнатурой может вызвать баг.
5. Подмена реализации
Использование интерфейса как типа может скрывать специфичное поведение конкретной реализации:
Дополнительные нюансы
1. Функциональные интерфейсы
С Java 8 появились интерфейсы с единственным абстрактным методом — функциональные интерфейсы. Они могут быть использованы с лямбда-выражениями:
2. Интерфейсы и обобщения
Интерфейсы часто комбинируются с generics для повышения универсальности:
3. Marker-интерфейсы
Некоторые интерфейсы, такие как Serializable или Cloneable, не содержат методов. Они используются как маркеры для определения поведения JVM или библиотек.
4. Интерфейсы и наследование
Интерфейс может наследовать другие интерфейсы:
5. Интерфейсы и динамические прокси
Через интерфейсы создаются динамические прокси, например, в java.lang.reflect.Proxy, что активно используется в Spring, Hibernate и других фреймворках.
#Java #для_новичков #beginner #reference_types #Interface
Классы в Java не могут наследовать более одного класса, но могут реализовать несколько интерфейсов:
public interface Flyable {
void fly();
}
public interface Swimmable {
void swim();
}
public class Duck implements Flyable, Swimmable {
public void fly() { ... }
public void swim() { ... }
}
Это решает проблему ограничений одиночного наследования и позволяет композировать поведение.
Трудности и подводные камни
1. Конфликт default-методов
Если класс реализует несколько интерфейсов, в которых есть default-методы с одинаковыми сигнатурами, возникает конфликт:
interface A {
default void show() { System.out.println("A"); }
}
interface B {
default void show() { System.out.println("B"); }
}
class C implements A, B {
public void show() {
A.super.show(); // Явное разрешение конфликта
}
}
2. Отсутствие состояния
Интерфейсы не могут содержать нестатические поля, что ограничивает их в сравнении с абстрактными классами. Всё, что можно объявить — это public static final константы.
3. Непредсказуемое поведение equals/hashCode
Если объект используется через интерфейс, его поведение equals() и hashCode() может зависеть от реализации, что важно при использовании в коллекциях.
4. Ошибки при переопределении
Ошибки в сигнатурах при реализации интерфейса не всегда очевидны. Например, случайное переопределение метода с другой сигнатурой может вызвать баг.
5. Подмена реализации
Использование интерфейса как типа может скрывать специфичное поведение конкретной реализации:
List<String> list = new LinkedList<>();
list.get(0); // Поведение может отличаться от ArrayList
Дополнительные нюансы
1. Функциональные интерфейсы
С Java 8 появились интерфейсы с единственным абстрактным методом — функциональные интерфейсы. Они могут быть использованы с лямбда-выражениями:
Runnable r = () -> System.out.println("Run");
2. Интерфейсы и обобщения
Интерфейсы часто комбинируются с generics для повышения универсальности:
public interface Repository<T> {
void save(T entity);
}
3. Marker-интерфейсы
Некоторые интерфейсы, такие как Serializable или Cloneable, не содержат методов. Они используются как маркеры для определения поведения JVM или библиотек.
4. Интерфейсы и наследование
Интерфейс может наследовать другие интерфейсы:
interface A { void a(); }
interface B extends A { void b(); }
Класс, реализующий B, обязан реализовать методы a() и b().
5. Интерфейсы и динамические прокси
Через интерфейсы создаются динамические прокси, например, в java.lang.reflect.Proxy, что активно используется в Spring, Hibernate и других фреймворках.
#Java #для_новичков #beginner #reference_types #Interface
Что выведет код?
#Tasks
interface A170625 {
default void show() {
System.out.println("A");
}
}
interface B170625 extends A170625 {
default void show() {
System.out.println("B");
}
}
interface C170625 extends A170625 {}
class D170625 implements B170625, C170625 {
public static void main(String[] args) {
new D170625().show();
}
}
#Tasks
Продолжаем выбирать темы для разбора и голосовать за рассмотрение предложенных! 🤓
Голосуем за тему к рассмотрению в эти выходные!
Выбираем новую тему!
(можете предложить что-то из того, что предлагали на прошлой и позапрошлых неделях и что проиграло в голосовании!)
Не стесняемся!✌️
Голосуем за тему к рассмотрению в эти выходные!
Выбираем новую тему!
(можете предложить что-то из того, что предлагали на прошлой и позапрошлых неделях и что проиграло в голосовании!)
Не стесняемся!
Please open Telegram to view this post
VIEW IN TELEGRAM
Чем отличается Iterator от ListIterator? 🤓
Ответ:
Iterator позволяет перебирать элементы коллекции в одном направлении и удалять их (remove()).
ListIterator расширяет Iterator для списков (List), добавляя возможность двунаправленного перебора (previous(), hasPrevious()) и модификации элементов (set()).
Пример:
List<String> list = new ArrayList<>(Arrays.asList("A", "B"));
ListIterator<String> it = list.listIterator();
it.next (); // Переход к "A"
it.set("C"); // Замена "A" на "C"
#собеседование
Ответ:
ListIterator расширяет Iterator для списков (List), добавляя возможность двунаправленного перебора (previous(), hasPrevious()) и модификации элементов (set()).
Пример:
List<String> list = new ArrayList<>(Arrays.asList("A", "B"));
ListIterator<String> it = list.listIterator();
it.set("C"); // Замена "A" на "C"
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
Интеграция Flyway с инструментами
1. Maven: плагин flyway-maven-plugin
Настройка в pom.xml:
Ключевые параметры:
url — JDBC-строка подключения.
locations — пути к папкам с миграциями (classpath: или filesystem:).
baselineVersion — версия для инициализации существующей БД (если не пустая).
Команды:
2. Gradle: плагин org.flywaydb.flyway
Настройка в build.gradle:
Команды:
3. Интеграция с Spring Boot
Автоконфигурация через application.yml:
Принцип работы:
При старте приложения Spring Boot автоматически:
Проверяет наличие таблицы flyway_schema_history.
Применяет невыполненные миграции из указанных в locations.
Если baseline-on-migrate: true, Flyway инициализирует БД без ошибок, даже если она не пуста.
Важные свойства:
spring.flyway.clean-disabled — запрет на случайную очистку БД (по умолчанию true в prod).
spring.flyway.table — кастомное имя для таблицы истории (по умолчанию flyway_schema_history).
4. Callbacks (SQL-хуки)
SQL-скрипты, выполняемые до/после основных операций Flyway (миграции, очистки и т.д.).
Поддерживаемые события:
beforeMigrate, afterMigrate
beforeClean, afterClean
beforeInfo, afterInfo
Пример использования:
Создайте файл db/migration/beforeMigrate.sql:
Flyway выполнит этот скрипт перед применением миграций.
Правила:
Имена файлов должны соответствовать шаблону: <event>.sql (например, afterMigrate.sql).
Размещаются в папке locations (рядом с миграциями).
5. Мультимодульные проекты (Maven/Gradle)
Если миграции находятся в отдельном модуле:
Укажите путь к ресурсам через filesystem::
6. Пропуск миграций в тестах
В application-test.yml:
7. Кастомные места хранения миграций
S3-хранилище (через Flyway Teams):
Классовый путь + файловая система:
#Java #middle #Flyway
1. Maven: плагин flyway-maven-plugin
Настройка в pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>9.22.0</version>
<configuration>
<url>jdbc:postgresql://localhost:5432/mydb</url>
<user>postgres</user>
<password>password</password>
<locations>
<location>classpath:db/migration</location>
</locations>
</configuration>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.6.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
Ключевые параметры:
url — JDBC-строка подключения.
locations — пути к папкам с миграциями (classpath: или filesystem:).
baselineVersion — версия для инициализации существующей БД (если не пустая).
Команды:
mvn flyway:migrate # Применить миграции
mvn flyway:info # Показать статус
mvn flyway:clean # Очистить БД (удалить все объекты)
2. Gradle: плагин org.flywaydb.flyway
Настройка в build.gradle:
plugins {
id "org.flywaydb.flyway" version "9.22.0"
}
flyway {
url = 'jdbc:postgresql://localhost:5432/mydb'
user = 'postgres'
password = 'password'
locations = ['classpath:db/migration']
}
dependencies {
flywayRuntime 'org.postgresql:postgresql:42.6.0'
}
Команды:
gradle flywayMigrate # Применить миграции
gradle flywayInfo # Показать статус
3. Интеграция с Spring Boot
Автоконфигурация через application.yml:
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: password
flyway:
enabled: true
locations: classpath:db/migration
baseline-on-migrate: true # Игнорировать существующую БД
validate-on-migrate: false # Отключить валидацию (для dev)
Принцип работы:
При старте приложения Spring Boot автоматически:
Проверяет наличие таблицы flyway_schema_history.
Применяет невыполненные миграции из указанных в locations.
Если baseline-on-migrate: true, Flyway инициализирует БД без ошибок, даже если она не пуста.
Важные свойства:
spring.flyway.clean-disabled — запрет на случайную очистку БД (по умолчанию true в prod).
spring.flyway.table — кастомное имя для таблицы истории (по умолчанию flyway_schema_history).
4. Callbacks (SQL-хуки)
SQL-скрипты, выполняемые до/после основных операций Flyway (миграции, очистки и т.д.).
Поддерживаемые события:
beforeMigrate, afterMigrate
beforeClean, afterClean
beforeInfo, afterInfo
Пример использования:
Создайте файл db/migration/beforeMigrate.sql:
-- beforeMigrate.sql
CREATE TABLE IF NOT EXISTS _flyway_audit (
operation VARCHAR(20),
timestamp TIMESTAMP
);
INSERT INTO _flyway_audit VALUES ('migration_started', NOW());
Flyway выполнит этот скрипт перед применением миграций.
Правила:
Имена файлов должны соответствовать шаблону: <event>.sql (например, afterMigrate.sql).
Размещаются в папке locations (рядом с миграциями).
5. Мультимодульные проекты (Maven/Gradle)
Если миграции находятся в отдельном модуле:
Укажите путь к ресурсам через filesystem::
<!-- Maven -->
<location>filesystem:${project.basedir}/../migrations/src/main/resources/db/migration</location>
// Gradle
locations = ['filesystem:../migrations/src/main/resources/db/migration']
6. Пропуск миграций в тестах
В application-test.yml:
spring:
flyway:
enabled: false
7. Кастомные места хранения миграций
S3-хранилище (через Flyway Teams):
spring:
flyway:
locations: s3://my-bucket/db/migration
Классовый путь + файловая система:
locations: classpath:db/migration, filesystem:/opt/migrations
#Java #middle #Flyway
Что выведет код?
#Tasks
import java.util.Optional;
public class Task180625 {
public static void main(String[] args) {
Optional<String> opt = Optional.ofNullable(null)
.flatMap(s -> Optional.of("value"))
.or(() -> Optional.of("default"));
System.out.println(opt.get());
}
}
#Tasks
Что такое try-with-resources? 🤓
Ответ:
try-with-resources (Java 7+) автоматически закрывает ресурсы, реализующие интерфейс AutoCloseable (например, FileInputStream). Это упрощает управление ресурсами, предотвращая утечки.
Пример:
try (FileInputStream fis = new FileInputStream("file.txt")) {
// Работа с файлом
} catch (IOException e) {
e.printStackTrace();
}
Ресурсы закрываются автоматически после выхода из блока try.
#собеседование
Ответ:
Пример:
try (FileInputStream fis = new FileInputStream("file.txt")) {
// Работа с файлом
} catch (IOException e) {
e.printStackTrace();
}
Ресурсы закрываются автоматически после выхода из блока try.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
Ссылочные типы в Java — var
Ключевое слово var, добавленное в Java 10, представляет собой локальную типизированную переменную с выводом типа (local variable type inference). Хотя var сам по себе не является типом (в отличие от String, List, и т.п.), он оперирует ссылочными (и примитивными) типами — именно поэтому мы рассматриваем его как часть экосистемы ссылочных типов.
var позволяет сократить синтаксис, делая код лаконичнее, при этом тип переменной всё равно строго определяется на этапе компиляции.
Синтаксис и пример использования
Это полностью эквивалентно:
Тип переменной вычисляется во время компиляции, и далее не может быть изменён. var нельзя использовать без инициализации:
Что происходит на уровне компиляции и памяти
На уровне байткода и JVM var не существует — это просто синтаксический сахар. Компилятор javac анализирует выражение справа от знака =, определяет точный тип и подставляет его вместо var.
Пример:
Компилируется в:
На уровне памяти всё ведёт себя так же, как если бы вы явно указали тип: объект User создаётся в куче (heap), а ссылка user — в стеке (если переменная локальная). То есть var никак не влияет на runtime-поведение, управление памятью или структуру объектов.
Где можно использовать var
Только внутри методов (локальные переменные)
В циклах for-each
В try-with-resources
Примеры:
Нельзя использовать:
Для параметров методов
Для полей классов
В сигнатурах методов
Преимущества использования var
1. Ускорение читаемости
→
Меньше дублирования, особенно при использовании дженериков.
2. Быстрая прототипизация
При тестировании и прототипах позволяет писать код быстрее.
3. Минимизация шаблонного кода
Особенно полезно в циклах:
Недостатки и подводные камни
1. Потеря явности
var может скрыть реальный тип переменной, что ухудшает читаемость, особенно в больших проектах или при чтении чужого кода:
2. Не подходит для API и контрактов
Вы не можете использовать var в методах, полях и интерфейсах, что делает его локальной удобной вещью, но не универсальным инструментом проектирования.
3. Опасности с null
Пример:
Тип должен быть определён по выражению. null без контекста не имеет типа.
4. Может скрыть ошибки
В случае приведения типов или неочевидных фабрик:
Программист может подумать, что это ArrayList.
5. Не подходит для примитивов, если важна производительность
Лучшие практики использования var
Использовать var, когда тип очевиден из правой части.
Не использовать в публичных API и библиотечном коде.
Избегать var, если тип сложный или поведение неочевидно.
Можно комбинировать с IDE: использовать var в коде, но просматривать тип через наведение мыши.
Пример хорошего использования:
Пример плохого использования:
#Java #для_новичков #beginner #reference_types #var
Ключевое слово var, добавленное в Java 10, представляет собой локальную типизированную переменную с выводом типа (local variable type inference). Хотя var сам по себе не является типом (в отличие от String, List, и т.п.), он оперирует ссылочными (и примитивными) типами — именно поэтому мы рассматриваем его как часть экосистемы ссылочных типов.
var позволяет сократить синтаксис, делая код лаконичнее, при этом тип переменной всё равно строго определяется на этапе компиляции.
Синтаксис и пример использования
var list = new ArrayList<String>();
var name = "John";
var age = 25;
Это полностью эквивалентно:
ArrayList<String> list = new ArrayList<>();
String name = "John";
int age = 25;
Тип переменной вычисляется во время компиляции, и далее не может быть изменён. var нельзя использовать без инициализации:
var name; // ошибка компиляции
Что происходит на уровне компиляции и памяти
На уровне байткода и JVM var не существует — это просто синтаксический сахар. Компилятор javac анализирует выражение справа от знака =, определяет точный тип и подставляет его вместо var.
Пример:
var user = new User("Alice");
Компилируется в:
User user = new User("Alice");
На уровне памяти всё ведёт себя так же, как если бы вы явно указали тип: объект User создаётся в куче (heap), а ссылка user — в стеке (если переменная локальная). То есть var никак не влияет на runtime-поведение, управление памятью или структуру объектов.
Где можно использовать var
Только внутри методов (локальные переменные)
В циклах for-each
В try-with-resources
Примеры:
for (var entry : map.entrySet()) {
...
}
try (var stream = Files.lines(path)) {
...
}
Нельзя использовать:
Для параметров методов
Для полей классов
В сигнатурах методов
Преимущества использования var
1. Ускорение читаемости
Map<String, List<User>> usersByRole = new HashMap<>();
→
var usersByRole = new HashMap<String, List<User>>();
Меньше дублирования, особенно при использовании дженериков.
2. Быстрая прототипизация
При тестировании и прототипах позволяет писать код быстрее.
3. Минимизация шаблонного кода
Особенно полезно в циклах:
for (var entry : map.entrySet()) { ... }
Недостатки и подводные камни
1. Потеря явности
var может скрыть реальный тип переменной, что ухудшает читаемость, особенно в больших проектах или при чтении чужого кода:
var x = process(); // Что возвращает process()? Map? List? String?
2. Не подходит для API и контрактов
Вы не можете использовать var в методах, полях и интерфейсах, что делает его локальной удобной вещью, но не универсальным инструментом проектирования.
3. Опасности с null
Пример:
var data = null; // ошибка компиляции: невозможно вывести тип
Тип должен быть определён по выражению. null без контекста не имеет типа.
4. Может скрыть ошибки
В случае приведения типов или неочевидных фабрик:
var list = Arrays.asList(1, 2, 3); // list: List<Integer>, но неизменяемый!
Программист может подумать, что это ArrayList.
5. Не подходит для примитивов, если важна производительность
var x = 42; // int
var y = 42L; // long
// Может быть неожиданным, если x и y пойдут в разные ветви перегрузки
Лучшие практики использования var
Использовать var, когда тип очевиден из правой части.
Не использовать в публичных API и библиотечном коде.
Избегать var, если тип сложный или поведение неочевидно.
Можно комбинировать с IDE: использовать var в коде, но просматривать тип через наведение мыши.
Пример хорошего использования:
var list = new ArrayList<String>(); // тип легко читается
Пример плохого использования:
var result = service.process(); // неясно, что такое result
#Java #для_новичков #beginner #reference_types #var
Что выведет код?
#Tasks
import java.util.function.Function;
public class Task190625 {
public static void main(String[] args) {
var x = (Function<Function<Integer, Integer>, Integer>)
f -> f.apply(10);
var y = x.apply(n -> n * 2);
System.out.println(y);
}
}
#Tasks
StreamAPI JAVA.
Великолепие минимализма
Видео посвященное изучению Stream API в Java.
Что мы узнали:
⏺ Что такое Stream API и зачем оно вообще нужно.
⏺ Что такое Императивный и Декларативный подходы.
⏺ Рассмотрели функциональные интерфейсы и их основные виды.
⏺ Рассмотрели основные функциональные промежуточные и терминальные методы.
⏺ Посмотрели все это на примерах.
Если хотите посмотреть с более подробными примерами и описанием:
GitHub - https://github.com/Oleborn/StreamAPI_Research
(понравилось - поставь звездочку)
Ссылка на Youtube
Ссылка на Рутьюб
Смотрите, ставьте лайки, подписывайтесь на каналы!
Великолепие минимализма
Видео посвященное изучению Stream API в Java.
Что мы узнали:
Если хотите посмотреть с более подробными примерами и описанием:
GitHub - https://github.com/Oleborn/StreamAPI_Research
Ссылка на Youtube
Ссылка на Рутьюб
Смотрите, ставьте лайки, подписывайтесь на каналы!
Please open Telegram to view this post
VIEW IN TELEGRAM
Что такое Error в Java и чем он отличается от Exception? 🤓
Ответ:
Error и Exception — наследники Throwable.
Error обозначает серьезные системные ошибки, которые обычно нельзя обработать (например, OutOfMemoryError).
Exception — это ошибки, которые можно и нужно обрабатывать (например, IOException).
Программист редко обрабатывает Error, но должен учитывать Exception.
#собеседование
Ответ:
Error обозначает серьезные системные ошибки, которые обычно нельзя обработать (например, OutOfMemoryError).
Exception — это ошибки, которые можно и нужно обрабатывать (например, IOException).
Программист редко обрабатывает Error, но должен учитывать Exception.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM