← Назад к вопросам

Расскажи про неудачи

1.0 Junior🔥 161 комментариев
#Soft Skills и карьера

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Обработка неудач: Exception Handling в Java

Обработка неудач — это критическое мастерство в разработке на Java. Речь идёт о том, как код реагирует на ошибки, исключительные ситуации и непредвиденные события.

Типы исключений в Java

Checked Exceptions (Проверяемые исключения)

Должны быть явно обработаны или объявлены в throws:

public class FileProcessor {
    public void readFile(String path) throws IOException {
        FileReader reader = new FileReader(path);
        reader.close();
    }
}

Примеры: IOException, SQLException, ParseException

Unchecked Exceptions (Необработанные исключения)

Наследуют RuntimeException, не требуют обработки:

public class Calculator {
    public int divide(int a, int b) {
        return a / b; // Может выбросить ArithmeticException
    }
}

Примеры: NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException

Обработка исключений: Try-Catch-Finally

public class BankService {
    public void transfer(Account from, Account to, double amount) {
        try {
            if (amount <= 0) {
                throw new IllegalArgumentException("Amount must be positive");
            }
            
            if (from.getBalance() < amount) {
                throw new InsufficientFundsException("Not enough balance");
            }
            
            from.withdraw(amount);
            to.deposit(amount);
            
        } catch (IllegalArgumentException e) {
            System.err.println("Invalid input: " + e.getMessage());
            // Логируем и обрабатываем специфичную ошибку
            
        } catch (InsufficientFundsException e) {
            System.err.println("Cannot transfer: " + e.getMessage());
            notifyUser("Transfer failed");
            
        } catch (Exception e) {
            System.err.println("Unexpected error: " + e);
            logger.error("Transfer failed unexpectedly", e);
            
        } finally {
            // Это выполнится ВСЕ РАВНО, даже если было исключение
            System.out.println("Transfer attempt completed");
            closeConnection();
        }
    }
}

Try-With-Resources (Автоматическая очистка)

public class SafeFileReader {
    public void readFile(String path) throws IOException {
        // Ресурс автоматически закроется
        try (FileReader reader = new FileReader(path);
             BufferedReader buffered = new BufferedReader(reader)) {
            
            String line;
            while ((line = buffered.readLine()) != null) {
                System.out.println(line);
            }
        } 
        // reader и buffered закроются автоматически
    }
}

Преимущество: не забудешь закрыть ресурс.

Custom исключения

// Создаём своё исключение
public class InsufficientFundsException extends Exception {
    private double required;
    private double available;
    
    public InsufficientFundsException(double required, double available) {
        super("Required: " + required + ", Available: " + available);
        this.required = required;
        this.available = available;
    }
    
    public double getShortfall() {
        return required - available;
    }
}

Использование:

if (balance < amount) {
    throw new InsufficientFundsException(amount, balance);
}

Обработка цепочек исключений

public class DataService {
    public User loadUser(int id) {
        try {
            return database.findUser(id);
        } catch (SQLException e) {
            // Оборачиваем в более высокоуровневое исключение
            throw new DataAccessException("Failed to load user: " + id, e);
        }
    }
}

Лучшие практики обработки ошибок

1. Не подавляй исключения

// ПЛОХО: проблема скрыта
try {
    processData();
} catch (Exception e) {
    // Молчание — золото? НЕТ!
}

// ХОРОШО: логируем и обрабатываем
try {
    processData();
} catch (Exception e) {
    logger.error("Processing failed", e);
    throw new ProcessingException("Data processing error", e);
}

2. Специфичные catch блоки

// ПЛОХО: ловим ВСЁ
try {
    operation();
} catch (Exception e) {
    handle(e);
}

// ХОРОШО: ловим конкретные ошибки
try {
    operation();
} catch (DatabaseException e) {
    handleDatabaseError(e);
} catch (ValidationException e) {
    handleValidationError(e);
} catch (RuntimeException e) {
    handleUnexpectedError(e);
}

3. Валидируй входные данные рано

public void createUser(String name, String email) {
    if (name == null || name.trim().isEmpty()) {
        throw new IllegalArgumentException("Name cannot be empty");
    }
    if (!isValidEmail(email)) {
        throw new IllegalArgumentException("Invalid email format");
    }
    // Теперь безопасно работать с данными
}

4. Используй Optional для null-safety

// ПЛОХО: NullPointerException может всплыть
User user = findUser(id);
String email = user.getEmail();

// ХОРОШО: явно обрабатываем null
Optional<User> user = findUser(id);
String email = user.map(User::getEmail).orElse("unknown@example.com");

Логирование ошибок

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class OrderService {
    private static final Logger logger = LoggerFactory.getLogger(OrderService.class);
    
    public void processOrder(Order order) {
        try {
            validateOrder(order);
            saveOrder(order);
            logger.info("Order processed successfully: {}", order.getId());
        } catch (ValidationException e) {
            logger.warn("Order validation failed: {}", e.getMessage());
        } catch (Exception e) {
            logger.error("Unexpected error processing order", e);
            sendAlertToAdmin(e);
        }
    }
}

Ключевые выводы

  • Не подавляй ошибки — логируй, обрабатывай, пробрасывай дальше если нужно
  • Специфичные исключения — лучше, чем ловля Exception
  • Валидируй рано — ошибки на входе лучше, чем внутри логики
  • Try-with-resources — используй для автоматической очистки
  • Custom исключения — делают код более читаемым
  • Optional вместо null — избегай NullPointerException
  • Логируй все ошибки — они помогают в отладке и мониторинге в продакшене
Расскажи про неудачи | PrepBro