Ошибка ввода данных java

есть метод, который запрашивает у пользователя данные (Имя,Фамилия, Год рождения, Год начала работы)
мне надо обработать исключения, если пользователь ввел в место чисел буквы(год рождения и год начало работы) и обработать если ввел буквы вместо чисел.
как это правильно сделать?
мой код:

public class Employee {
public void readData(){
   Scanner scanner = new Scanner(System.in);
    try {
        System.out.println("Введите дата рождения: ");
        int birthDate = Integer.parseInt(scanner.next());
        System.out.println("Введите начало год работы: ");
        int startWorking = Integer.parseInt(scanner.next());
        if (birthDate > 2021 || startWorking > 2021){
            System.out.println("Are you from future?! ");
            scanner.close();
        }
        if(startWorking - (2021 - birthDate) > birthDate){
            System.out.println("Не коректные данные!");
            scanner.close();
        }
        System.out.println("Введите имя: ");
        String name = scanner.next();
        System.out.println("Введите фамилию:");
        String lastName = scanner.nextLine();
        scanner.close();

    }
    catch (NumberFormatException | InputMismatchException exception){
        System.out.println("Введите коректные данные!");
    }
}

}

задан 14 янв 2021 в 8:15

omur turdubekov's user avatar

omur turdubekovomur turdubekov

351 золотой знак1 серебряный знак7 бронзовых знаков

Если при невалидном вводе нужно именно кидать эксепшн, то:

public static void main(String[] args) {
    try (Scanner sc = new Scanner(System.in)) {
        System.out.println("Insert int value");
        printValidValue(sc, "[0-9]+");

        System.out.println("Insert name");
        printValidValue(sc, "[a-zA-Z]+");            
    }
}

static void printValidValue(Scanner sc, String pattern) {
    while (sc.hasNextLine()) {
        try {
            System.out.println("Value accepted: " + sc.next(pattern));
            break;
        } catch (InputMismatchException e) {
            System.out.println("Invalid value");
            sc.nextLine();
        }
    }
}

ответ дан 14 янв 2021 в 10:55

pazukdev's user avatar

Попытайтесь распарсить входную строку при помощи Integer.parseInt(). Если формат строки не будет соответствовать числу, будет выброшена ошибка NumberFormatException. Вы можете перехватить её при помощи try…catch:

try {
    Integer num = Integer.pasrseInt(str);
} catch (NumberFormatException e) {
    // действия по обработке ошибки
}

ответ дан 14 янв 2021 в 8:36

Zhenyria's user avatar

ZhenyriaZhenyria

2,0642 золотых знака13 серебряных знаков42 бронзовых знака

4

Глава 9

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

Основные навыки и понятия

  • Представление об иерархии исключений
  • Использование ключевых слов try и catch
  • Последствия неперехвата исключений
  • Применение нескольких операторов catch
  • Перехват исключений, генерируемых подклассами
  • Вложенные блоки try
  • Генерирование исключений
  • Представление о членах класса Throwable
  • Использование ключевого слова finally
  • Использование ключевого слова throws
  • Представление о исключениях, встроенные в Java
  • Создание специальных классов исключений

В этой главе речь пойдет об обработке исключительный ситуаций, или просто исключений. Исключение — это ошибка, возникающая в процессе выполнения программы. Используя подсистему обработки исключений Java, можно контролировать реакцию программы на появление ошибок в ходе ее выполнения. Средства обработки исключений в том или ином виде присутствуют практически во всех современных языках программирования. Можно смело утверждать, что в Java подобные инструментальные средства отличаются большей гибкостью, более понятны и удобны в употреблении по сравнению с большинством других языков программирования.

Преимущество обработки исключений заключается в том, что она автоматически предусматривает реакцию на многие ошибки, избавляя от необходимости писать вручную соответствующий код. Например, в некоторых старых языках программирования предусматривается возврат специального кода при возникновении ошибки в ходе выполнения метода. Этот код приходится проверять вручную при каждом вызове метода. Такой подход к обработке ошибок вручную трудоемок и чреват погрешностями. Обработка исключений упрощает этот процесс, давая возможность определять в программе блок кода, называемый обработчиком исключения и автоматически выполняющийся при возникновении ошибки. Это избавляет от необходимости проверять вручную, насколько удачно или неудачно была выполнена та или иная операция или вызов метода. Если возникнет ошибка, все необходимые действия по ее обработке выполнит обработчик исключений.

В Java определены стандартные исключения для наиболее часто встречающихся программных ошибок, в том числе деления на нуль или попытки открыть несуществующий файл. Для того чтобы обеспечить требуемую реакцию на конкретную ошибку, в программу следует включить соответствующий обработчик событий. Исключения широко применяются в библиотеке Java API.

Иерархия исключений

В Java все исключения представлены отдельными классами. Все классы исключений являются потомками класса Throwable. Так, если в программе возникнет исключительная ситуация, будет сгенерирован объект класса, соответствующего определенному типу исключения. У класса Throwable имеются два непосредственных подкласса: Exception и Error. Исключения типа Error относятся к ошибкам, возникающим в виртуальной машине Java, а не в прикладной программе. Контролировать такие исключения невозможно, поэтому реакция на них в прикладной программе, как правило, не предусматривается. В связи с этим исключения данного типа не будут описываться в этой книге.

Ошибки, связанные с выполнением действий в программе, представлены отдельными подклассами, производными от класса Exception. К этой категории, в частности, относятся ошибки деления на нуль, выхода за границы массива и обращения к файлам. Подобные ошибки следует обрабатывать в самой программе. Важным подклассом, производным от Exception, является класс RuntimeException, который служит для представления различных видов ошибок, часто встречающихся при выполнении программ.

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

Для обработки исключений в Java предусмотрены пять ключевых слов: try, catch, throw, throws и finally. Они образуют единую подсистему, в которой использование одного ключевого слова почти всегда автоматически влечет за собой употребление другого. Каждое из упомянутых выше ключевых слов будет подробно рассмотрено далее в этой главе. Но прежде следует дать общее представление об их роли в процессе обработки исключений. Поэтому ниже поясняется вкратце, каким образом они действуют.

Операторы, в которых требуется отслеживать появление исключений, помещаются в блок try. Если в блоке try будет сгенерировано исключение, его можно перехватить и обработать нужным образом. Системные исключения генерируются автоматически. А для того чтобы сгенерировать исключение вручную, следует воспользоваться ключевым словом throw. Иногда возникает потребность обрабатывать исключения за пределами метода, в котором они возникают, и для этой цели служит ключевое слово throws. Если же некоторый фрагмент кода должен быть выполнен обязательно и независимо от того, возникнет исключение или нет, его следует поместить в блок finally.

Использование ключевых слов try и catch

Основными языковыми средствами обработки исключений являются ключевые слова try и catch. Они используются совместно. Это означает, что нельзя указать ключевое слово catch в коде, не указав ключевое слово try. Ниже приведена общая форма записи блоков try/catch, предназначенных для обработки исключений.

try {
    // Блок кода, в котором должны отслеживаться ошибки
}
catch (тип_исключения_1 объект_исключения) {
    // Обработчик исключения тип_исключения_1
}
catch (тип_исключения_2 объект_исключения) {
    // Обработчик исключения тип_исключения_2
}

В скобках, следующих за ключевым словом catch, указываются тип исключения и переменная, ссылающаяся на объект данного типа. Когда возникает исключение, оно перехватывается соответствующим оператором catch, обрабатывающим это исключение. Как следует из приведенной выше общей формы записи, с одним блоком try может быть связано несколько операторов catch. Тип исключения определяет, какой именно оператор catch будет выполняться. Так, если тип исключения соответствует типу оператора catch, то именно он и будет выполнен, а остальные операторы catch — пропущены. При перехвате исключения переменной, указанной в скобках после ключевого слова catch, присваивается ссылка на объект_исключения.

Следует иметь в виду, что если исключение не генерируется, блок try завершается обычным образом и ни один из его операторов catch не выполняется. Выполнение программы продолжается с первого оператора, следующего за последним оператором catch. Таким образом, операторы catch выполняются только при появлении исключения.

На заметку.
В версии JDK 7 внедрена новая форма оператора try, поддерживающая автоматическое управления ресурсами и называемая оператором try с ресурсами. Более подробно она описывается в главе 10 при рассмотрении потоков ввода-вывода, в том числе и тех, что связаны с файлами, поскольку потоки ввода-вывода относятся к числу ресурсов, наиболее употребительных в прикладных программах.

Простой пример обработки исключений

Рассмотрим простой пример, демонстрирующий перехват и обработку исключения. Как известно, попытка обратиться за границы массива приводит к ошибке, и виртуальная машина Java генерирует соответствующее исключение ArraylndexOutOf BoundsException. Ниже приведен код программы, в которой намеренно создаются условия для появления данного исключения, которое затем перехватывается.

// Демонстрация обработки исключений,
class ExcDemol {
    public static void main (String args[]) {
        int nums[] = new int[4];

        // Создание блока try.
        try {
            System.out.println("Before exception is generated.");

            // Попытка обратиться за границы массива.
            nums[7] = 10;
            System.out.println("this won't be displayed");
        }
        // Перехват исключения в связи с обращением за границы массива.
        catch (ArraylndexOutOfBoundsException exc) {
            System.out.println("Index out-of-bounds!");
        }
        System.out.println("After catch statement.");
    }
}

Результат выполнения данной программы выглядит следующим образом:

Before exception is generated.
Index out-of-bounds!
After catch statement.

Несмотря на всю простоту данного примера программы, он наглядно демонстрирует несколько важных особенностей обработки исключений. Во-первых, код, подлежащий проверке на наличие ошибок, помещается в блок try. И во-вторых, когда возникает исключение (в данном случае это происходит при попытке обратиться за границы массива), выполнение блока try прерывается и управление получает блок catch. Следовательно, явного обращения к блоку catch не происходит, но переход к нему осуществляется лишь при определенном условии, возникающем в ходе выполнения программы. Так, оператор вызова метода println(), следующий за выражением, в котором происходит обращение к несуществующему элементу массива, вообще не выполняется. По завершении блока catch выполнение программы продолжается с оператора, следующего за этим блоком. Таким образом, обработчик исключений предназначен для устранения программных ошибок, приводящих к исключительным ситуациям, а также для обеспечения нормального продолжения исполняемой программы.

Как упоминалось выше, если в блоке try не возникнут исключения, операторы в блоке catch не получат управление и выполнение программы продолжится после блока catch. Для того чтобы убедиться в этом, измените в предыдущей программе строку кода

на следующую строку кода:

Теперь исключение не возникнет и блок catch не выполнится.

Важно понимать, что исключения отслеживаются во всем коде в блоке try. К их числу относятся исключения, которые могут быть сгенерированы методом, вызываемым из блока try. Исключения, возникающие в вызываемом методе, перехватываются операторами в блоке catch, связанном с блоком try. Правда, это произойдет лишь в том случае, если метод не обрабатывает исключения самостоятельно. Рассмотрим в качестве примера следующую программу:

/* Исключение может быть сгенерировано одним методом,
   а перехвачено другим. */

class ExcTest {
    // сгенерировать исключение
    static void genException()  {
        int nums[] = new int[4];

        System.out.println("Before exception is generated.");

        // Здесь генерируется исключение в связи с
        // обращением за границы массива.
        nums[7] = 10;
        System.out.println("this won't be displayed");
    }
}

class ExcDemo2 {
    public static void main(String args[])  {
        try {
            ExcTest.genException() ;
        }
        //А здесь исключение перехватывается.
        catch (ArraylndexOutOfBoundsException exc) {
            System.out.println("Index out-of-bounds!");
        }
        System.out.println("After catch statement.");
    }
}

Выполнение этой версии программы дает такой же результат, как и при выполнении ее предыдущей версии. Этот результат приведен ниже.

Before exception is generated.
Index out-of-bounds!
After catch statement.

Метод genException() вызывается из блока try, и поэтому генерируемое, но не перехватываемое в нем исключение перехватывается далее в блоке catch в методе main(). Если бы метод genException() сам перехватывал исключение, оно вообще не дошло бы до метода main().

Последствия неперехвата исключений

Перехват стандартного исключения Java, продемонстрированный в предыдущем примере, позволяет предотвратить завершение программы вследствие ошибки. Генерируемое исключение должно быть перехвачено и обработано. Если исключение не обрабатывается в программе, оно будет обработано виртуальной машиной Java. Но дело в том, что по умолчанию виртуальная машина Java аварийно завершает программу, выводя сообщение об ошибке и трассировку стека исключений. Допустим, в предыдущем примере попытка обращения за границы массива не отслеживается и исключение не перехватывается, как показано ниже.

// Обработка ошибки средствами виртуальной машины Java,
class NotHandled {
    public static void main(String args[]) {
        int nums[] = new int[4];

        System.out.println("Before exception is generated.");

        // Попытка обращения за границы массива,
        nums[7] = 10;
    }
}

При появлении ошибки, связанной с обращением за границы массива, выполнение программы прекращается и выводится следующее сообщение:

Exception in thread "main" java.lang.ArraylndexOutOfBoundsException: 7 at NotHandled.main(NotHandled.java:9)

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

Как упоминалось выше, тип исключения должен соответствовать типу, указанному в операторе catch. В противном случае исключение не будет перехвачено. Так, в приведенном ниже примере программы делается попытка перехватить исключение, связанное с обращением за границы массива, с помощью оператора catch, в котором указан тип ArithmeticException еще одного встроенного в Java исключения. При неправильном обращении к массиву будет сгенерировано исключение ArraylndexOutOfBoundsException, не соответствующее типу, указанному в операторе catch. В результате программа будет завершена аварийно.

// Эта программа не будет работать нормально!
class ExcTypeMismatch {
    public static void main(String args[]) {
        int nums[] = new int[4];
        try {
        System.out.println("Before exception is generated.");
        // При выполнении следующего оператора возникает
        // исключение ArraylndexOutOfBoundsException
        nums[7] = 10;
        System.out.println("this won’t be displayed");
        }
        /* Исключение, связанное с обращением за границы массива,
        нельзя обработать с помощью оператора catch, в котором
        указан тип исключения ArithmeticException. */
        catch (ArithmeticException exc) {
        System.out.println("Index out-of-bounds!");
        }
        System.out.println("After catch statement.");
    }
}

Ниже приведен результат выполнения данной программы.

Before exception is generated.
Exception in thread "main" java.lang.ArraylndexOutOfBoundsException: 7
    at ExcTypeMismatch.main(ExcTypeMismatch.java:10)

Нетрудно заметить, что оператор catch, в котором указан тип исключения ArithmeticException, не может перехватить исключение ArraylndexOutOfBoundsException.

Обработка исключений — изящный способ устранения программных ошибок

Одно из главных преимуществ обработки исключений заключается в том, что она позволяет вовремя отреагировать на ошибку в программе и затем продолжить ее выполнение. В качестве примера рассмотрим еще одну программу, в которой элементы одного массива делятся на элементы другого. Если при этом происходит деление на нуль, то генерируется исключение ArithmeticException. Обработка подобного исключения заключается в том, что программа уведомляет об ошибке и затем продолжает свое выполнение. Таким образом, попытка деления на нуль не приведет к аварийному завершению программы из-за ошибки при ее выполнении. Вместо этого ошибка обрабатывается изящно, не прерывая выполнение программы.

// Изящная обработка исключения и продолжение выполнения программы,
class ExcDemo3 {
    public static void main(String args[])  {
        int numer[] = { 4, 8, 16, 32, 64, 128 };
        int denom[] = { 2, 0, 4, 4, 0, 8 };

        for(int i=0; i<numer.length; i++)   {
            try {
                System.out.println(numer[i] + " / " +
                                   denom[i] + " is " +
                                   numer[i]/denom[i]);
            }
            catch (ArithmeticException exc) {
                // перехватить исключение
                System.out.println("Can't divide by Zero!");
            }
        }
    }
}

Результат выполнения данной программы выглядит следующим образом:

4 / 2 is 2
Can't divide by Zero!
16/ 4 is 4
32 / 4 is 8
Can't divide by Zero!
128 / 8 is 16

Данный пример демонстрирует еще одну важную особенность: обработанное исключение удаляется из системы. Иными словами, на каждом шаге цикла блок try выполняется в программе сызнова, а все возникшие ранее исключения считаются обработанными. Благодаря этому в программе могут обрабатываться повторяющиеся ошибки.

Применение нескольких операторов catch

Как пояснялось ранее, с блоком try можно связать несколько операторов catch. Обычно разработчики так и поступают на практике. Каждый из операторов catch должен перехватывать отдельный тип исключений. Например, в приведенной ниже программе обрабатываются как исключения, связанные с обращением за границы массива, так и ошибки деления на нуль.

// Применение нескольких операторов catch.  '
class ExcDemo4 {
    public static void main(String args[]) {
        // Здесь массив numer длиннее массива denom.
        int numer[] = { 4, 8, 16, 32, 64, 128, 256, 512 };
        int denom[] = { 2, 0, 4, 4, 0, 8 };

        for(int i=0; i<numer.length; i++)   {
            try {
                System.out.println(numer[i] + " / " +
                                   denom[i] + " is " +
                                   numer[i]/denom[i]);
            }
            // За блоком try следует несколько блоков catch подряд,
            catch (ArithmeticException exc) {
                // перехватить исключение
                System.out.println("Can't divide by Zero!");
            }
            catch (ArraylndexOutOfBoundsException exc) {
                // перехватить исключение
                System.out.println("No matching element found.");
            }
        }
    }
}

Выполнение этой программы дает следующий результат:

4 / 2 is 2
Can't divide by Zero!
16 / 4 is 4
32 / 4 is 8
Can't divide by Zero!
128 / 8 is 16
No matching element found.
No matching element found.

Как подтверждает приведенный выше результат выполнения программы, в каждом блоке оператора catch обрабатывается свой тип исключения.

Вообще говоря, выражения с операторами catch проверяются в том порядке, в котором они встречаются в программе. И выполняется лишь тот из них, который соответствует типу возникшего исключения. А остальные блоки операторов catch просто игнорируются.

Перехват исключений, генерируемых подклассами

В отношении подклассов следует отметить еще одну интересную особенность применения нескольких операторов catch: условие перехвата исключений для суперкласса будет справедливо и для любых его подклассов. Например, класс Throwable является суперклассом для всех исключений, поэтому для перехвата всех возможных исключений в операторах catch следует указывать тип Throwable. Если же требуется перехватывать исключения типа суперкласса и типа подкласса, то в блоке операторов первым должен быть указан тип исключения, генерируемого подклассом. В противном случае вместе с исключением типа суперкласса будут перехвачены и все исключения производных от него классов. Это правило соблюдается автоматически, и если указать первым тип исключения, генерируемого суперклассом, то будет создан недостижимый код, поскольку условие перехвата исключения, генерируемого подклассом, никогда не будет выполнено. А ведь недостижимый код в Java считается ошибкой.

Рассмотрим в качестве примера следующую программу

//В операторах catch исключения типа подкласса должны
// предшествовать исключениям типа суперкласса,
class ExcDemo5 {
    public static void main(String args[]) {
        // Здесь массив numer длиннее массива denom.
        int numer[] = { 4, 8, 16, 32, 64, 128, 256, 512 };
        int denom[] = { 2, 0, 4, 4, 0, 8 };

        for(int i=0; i<numer.length; i++)   {
            try {
                System.out.println(numer[i] + " / " +
                                   denom[i] + " is " +
                                   numer[i]/denom[i]);
            }
            // Перехват исключения от подкласса.
            catch (ArraylndexOutOfBoundsException exc) {
                System.out.println("No matching element found.");
            }
            // Перехват исключения от суперкласса.
            catch (Throwable exc) {
                System.out.println("Some exception occurred.");
            }
        }
    }
}

Ниже приведен результат выполнения данной программы.

4 / 2 is 2
Some exception occurred.
16 / 4 is 4
32 / 4 is 8
Some exception occurred.
128 / 8 is 16
No matching element found.
No matching element found.

В данном случае оператор catch (Throwable) перехватывает все исключения, кроме ArraylndexOutOfBoundsException. Соблюдение правильного порядка следования операторов catch приобретает особое значение в том случае, когда исключения генерируются в самой программе.

Вложенные блоки try

Блоки try могут быть вложенными друг в друга. Исключение, возникшее во внутреннем блоке try и не перехваченное связанным с ним блоком catch, распростра¬няется далее во внешний блок try и обрабатывается связанным с ним блоком catch. Такой порядок обработки исключений демонстрируется в приведенном ниже примере программы, где исключение ArraylndexOutOfBoundsException не перехватывается во внутреннем блоке catch, но обрабатывается во внешнем.

// Применение вложенных блоков try.
class NestTrys {
    public static void main(String args[]) {
        // Массив numer длиннее, чем массив denom.
        int numer[] = { 4, 8, 16, 32, 64, 128, 256, 512 };
        int denom[] = { 2, 0, 4, 4, 0, 8 };

        // Вложенные блоки try.
        try { // Внешний блок try.
            for(int i=0; i<numer.length; i++)   {
                try { // Внутренний блок try.
                    System.out.println(numer[i] + " / " +
                                       denom[i] + " is " +
                                       numer[i]/denom[i]) ;
                }
                catch (ArithmeticException exc) {
                    // перехватить исключение
                    System.out.println("Can't divide by Zero!");
                }
            }
        }
        catch (ArraylndexOutOfBoundsException exc) {
            // перехватить исключение
            System.out.println("No matching element found.");
            System.out.println("Fatal error - program terminated.");
        }
    }
}

Выполнение этой программы может дать, например, следующий результат:

4 / 2 is 2
Can't divide by Zero!
16 / 4 is 4
32 / 4 is 8
Can't divide by Zero!
128 / 8 is 16
No matching element found.
Fatal error - program terminated.

В данном примере исключение, которое может быть обработано во внутреннем блоке try (в данном случае ошибка деления на нуль), не мешает дальнейшему выполнению программы. А вот ошибка превышения границ массива перехватывается во внешнем блоке try, что приводит к аварийному завершению программы.

Ситуация, продемонстрированная в предыдущем примере, является не единственной причиной для применения вложенных блоков try, хотя она встречается очень часто. В этом случае вложенные блоки try помогают по-разному обрабатывать разные типы ошибок. Одни ошибки невозможно устранить, а для других достаточно предусмотреть сравнительно простые действия. Внешний блок try чаще всего используется для перехвата критических ошибок, а менее серьезные ошибки обрабатываются во внутреннем блоке try.

Генерирование исключений

В предыдущих примерах программ обрабатывались исключения, автоматически генерируемые виртуальной машиной Java. Но генерировать исключения можно и вручную, используя для этого оператор throw. Ниже приведена общая форма этого оператора.

где объект_исключения должен быть объектом класса, производного от класса Throwable.

Ниже приведен пример программы, демонстрирующий применение оператора throw. В этой программе исключение ArithmeticException генерируется вручную.

// Генерирование исключения вручную,
class ThrowDemo {
    public static void main(String args[])  {
        try {
            System.out.println("Before throw.");
                // Генерирование исключения.
                throw new ArithmeticException() ;
        }
        catch (ArithmeticException exc) {
            // перехватить исключение
            System.out.println("Exception caught.");
        }

        System.out.println("After try/catch block.");
    }
}

Выполнение этой программы дает следующий результат:

Before throw.
Exception caught.
After try/catch block.

Обратите внимание на то, что исключение ArithmeticException генерируется с помощью ключевого слова new в операторе throw. Дело в том, что оператор throw генерирует исключение в виде объекта. Поэтому после ключевого слова throw недостаточно указать только тип исключения, нужно еще создать объект для этой цели.

Повторное генерирование исключений

Исключение, перехваченное блоком catch, может быть повторно сгенерировано для обработки другим аналогичным блоком. Чаще всего повторное генерирование исключений применяется с целью предоставить разным обработчикам доступ к исключению. Так, например, повторное генерирование имеет смысл в том случае, если один обработчик оперирует одним свойством исключения, а другой обработчик ориентирован на другое его свойство. Повторно сгенерированное исключение не может быть перехвачено тем же самым блоком catch. Оно распространяется в другие блоки catch.

Ниже приведен пример программы, демонстрирующий повторное генерирование исключений.

//•Повторное генерирование исключений,
class Rethrow {
    public static void genException()   {
        // Массив numer длиннее маесивв denom.
        int numer[] = { 4, 8, 16, 32, 64, 128, 256, 512 };
        int denom[] = { 2, 0, 4, 4, 0, 8 };

        for(int i=0; i<numer.length; i++)   {
            try {
                System.out.println(numer[i] + " / " +
                                   denom[i] + " is " +
                                   numer[i]/denom[i]);
            }
            catch (ArithmeticException exc) {
                // перехватить исключение
                System.out.println("Can11 divide by Zero!");
            }
            catch (ArraylndexOutOfBoundsException exc) {
                // перехватить исключение
                System.out.println("No matching element found.");
                throw exc; // Повторное генерирование исключения.
            }
        }
    }
}

class RethrowDemo {
    public static void main(String args[])  {
        try {
            Rethrow.genException();
        }
        catch(ArraylndexOutOfBoundsException exc) {
            // Перехват повторно сгенерированного включения.
            System.out.println("Fatal error - " +
                               "program terminated.");
        }
    }
}

В данной программе ошибка деления на нуль обрабатывается локально в методе genException(), а при попытке обращения за границы массива исключение генерируется повторно. На этот раз оно перехватывается в методе main().

Подробнее о классе Throwable

В приведенных до сих примерах программ только перехватывались исключения, но не выполнялось никаких действий над представляющими их объектами. В выражении оператора catch указываются тип исключения и параметр, принимающий объект исключения. А поскольку все исключения представлены подклассами, производными от класса Throwable, то они поддерживают методы, определенные в этом классе. Некоторые наиболее употребительные методы из класса Throwable приведены в табл. 9.1.

Таблица 9.1. Наиболее употребительные методы из класса Throwable

Метод Описание
Throwable filllnStackTrace() Возвращает объект типа Throwable, содержащий полную трассировку стека исключений. Этот объект пригоден для повторного генерирования исключений
String getLocalizedMessage() Возвращает описание исключения, локализованное по региональным стандартам
String getMessage() Возвращает описание исключения
void printStackTrace() Выводит трассировку стека исключений
void printStackTrace(PrintStream stream) Выводит трассировку стека исключений в указанный поток
void printStackTrace(PrintWriter stream) Направляет трассировку стека исключений в указанный поток
String toString() Возвращает объект типа String, содержащий полное описание исключения. Этот метод вызывается из метода println() при выводе объекта типа Throwable

Среди методов, определенных в классе Throwable, наибольший интерес представляют методы pr intStackTrace() и toString(). С помощью метода printStackTrace() можно вывести стандартное сообщение об ошибке и запись последовательности вызовов методов, которые привели к возникновению исключения, А метод toString() позволяет получить стандартное сообщение об ошибке. Этот метод также вызывается в том случае, когда объект исключения передается в качестве параметра методу println(). Применение этих методов демонстрируется в следующем примере программы:

// Применение методов из класса Throwable.
class ExcTest {
    static void genException()  {
        int nums[] = new int[4];

        System.out.println("Before exception is generated.");

        // сгенерировать исключение в связи с попыткой
        // обращения за границы массива
        nums[7] = 10;
        System.out.println("this won't be displayed");
    }
}

class UseThrowableMethods {
    public static void main(String args[])  {

        try {
            ExcTest.genException() ;
        }
        catch (ArraylndexOutOfBoundsException exc) {
            // перехватить исключение
            System.out.println("Standard message is: ");
            System.out.println(exc) ;
            System.out.println("nStack trace: ");
            exc.printStackTrace();
        }

        System.out.println("After catch statement.");
    }
}

Результат выполнения данной программы выглядит следующим образом:

Before exception is generated.
Standard message is:
java.lang.ArraylndexOutOfBoundsException: 7

Stack trace:
java.lang.ArraylndexOutOfBoundsException: 7
    at ExcTest.genException(UseThrowableMethods.java:10)
    at UseThrowableMethods.main(UseThrowableMethods.java:19)
After catch statement.

Использование ключевого слова finally

Иногда требуется определить кодовый блок, который должен выполняться по завершении блока try/catch. Допустим, в процессе работы программы возникло исключение, требующее ее преждевременного завершения. Но в программе открыт файл или установлено сетевое соединение, а следовательно, файл нужно закрыть, а соединение разорвать. Для выполнения подобных операций нормального завершения программы удобно воспользоваться ключевым словом finally.

Для того чтобы определить код, который должен выполняться по завершении блока try/catch, нужно указать блок finally в конце последовательности операторов try/catch. Ниже приведена общая форма записи блока try/catch вместе с блоком finally.

try {
    // Блок кода, в котором отслеживаются ошибки.
}
catch (тип_исключения_1 объект_исключения) {
    // Обработчик исключения тип_исключения_1
}
catch (тип_исключения_2 объект_исключения) {
    // Обработчик исключения тип_исключения_2
}
//. . .
finally {
// Код блока finally
}

Блок finally выполняется всегда по завершении блока try/catch независимо от того, какое именно условие к этому привело. Следовательно, блок finally получит управление как при нормальной работе программы, так и при возникновении ошибки. Более того, он будет вызван даже в том случае, если в блоке try или в одном из блоков catch будет присутствовать оператор return для немедленного возврата из метода.

Ниже приведен краткий пример программы, демонстрирующий применение блока finally.

// Применение блока finally,
class UseFinally {
    public static void genException(int what) {
        int t;
        int nums[] = new int[2];

        System.out.println("Receiving " + what);
        try {
            switch(what) {
            case 0:
                t = 10 / what; // сгенерировать ошибку деления на нуль
                break;
            case 1:
                nums[4] = 4; // сгенерировать ошибку обращения к массиву
                break;
            case 2:
                return; // возвратиться из блока try
            }
        }
        catch (ArithmeticException exc) {
            // перехватить исключение
            System.out.println("Can1t divide by Zero!");
            return; // возвратиться из блока catch
        }
        catch (ArraylndexOutOfBoundsException exc) {
            // перехватить исключение
            System.out.println("No matching element found.");
        }
        // Этот блок выполняется независимо от того, каким
        // образом завершается блок try/catch.
        finally {
            System.out.println("Leaving try.");
        }
    }
}

class FinallyDemo {
    public static void main(String args[]) {

        for(int i=0; i < 3; i++) {
            UseFinally.genException(i);
            System.out.println() ;
        }
    }
}

В результате выполнения данной программы получается следующий результат:

Receiving О
Can't divide by Zero!
Leaving try.

Receiving 1
No matching element found.
Leaving try.

Receiving 2
Leaving try.

Нетрудно заметить, что блок finally выполняется независимо от того, каким об¬
разом завершается блок try/catch.

Использование ключевого слова throws

Иногда исключения нецелесообразно обрабатывать в том методе, в котором они возникают. В таком случае их следует указывать с помощью ключевого слова throws. Ниже приведена общая форма объявления метода, в котором присутствует ключевое слово throws.

возвращаемый_тип имя_метода(список_параметров) throws список_исключений {
    // Тело метода
}

В списке исключений через запятую указываются исключения, которые может генерировать метод.

Возможно, вам покажется странным, что в ряде предыдущих примеров ключевое слово throws не указывалось при генерировании исключений за пределами методов. Дело в том, что исключения, генерируемые подклассом Error или RuntimeException, можно и не указывать в списке оператора throws. Исполняющая система Java по умолчанию предполагает, что метод может их генерировать. А исключения всех остальных типов следует непременно объявить с помощью ключевого слова throws. Если этого не сделать, возникнет ошибка при компиляции.

Пример применения оператора throws уже был представлен ранее в этой книге.
Напомним, что при организации ввода с клавиатуры в метод main() потребовалось
включить следующее выражение:

throws java.io.IOException

Теперь вы знаете, зачем это было нужно. При вводе данных может возникнуть исключение IOException, а на тот момент вы еще не знали, как оно обрабатывается. Поэтому мы и указали, что исключение должно обрабатываться за пределами метода main(). Теперь, ознакомившись с исключениями, вы сможете без труда обработать исключение IOException самостоятельно.

Рассмотрим пример, в котором осуществляется обработка исключения IOException. В методе prompt() отображается сообщение, а затем выполняется ввод символов с клавиатуры. Такой ввод данных может привести к возникновению исключения IOException. Но это исключение не обрабатывается в методе prompt(). Вместо этого в объявлении метода указан оператор throws, т.е. обязанности по обработке данного исключению поручаются вызывающему методу. В данном случае вызывающим является метод main(), в котором и перехватывается исключение.

// Применение ключевого слова throws,
class ThrowsDemo {
    // Обратите внимание на оператор throws в объявлении метода.
    public static char prompt(String str)
        throws java.io.IOException {

        System.out.print(str + ": ");
        return (char) System.in.read() ;
    }

    public static void main(String args[]) {
        char ch;

        try {
            // В методе prompt() может быть сгенерировано исключение,
            // поэтому данный метод следует вызывать в блоке try.
            ch = prompt("Enter a letter");
        }
        catch(java.io.IOException exc) {
            System.out.println("I/O exception occurred.");
            ch = 'X';
        }
        System.out.println("You pressed " + ch);
    }
}

Обратите внимание на одну особенность приведенного выше примера. Класс IOException относится к пакету java. io. Как будет разъяснено в главе 10, в этом пакете содержатся многие языковые средства Java для организации ввода-вывода. Следовательно, пакет java.io можно импортировать, а в программе указать только имя класса IOException.

Новые средства обработки исключений, внедренные в версии JDK 7

С появлением версии JDK 7 механизм обработки исключений в Java был значительно усовершенствован благодаря внедрению трех новых средств. Первое из них поддерживает автоматическое управление ресурсами, позволяющее автоматизировать процесс освобождения таких ресурсов, как файлы, когда они больше не нужны. В основу этого средства положена расширенная форма оператора try, называемая оператором try с ресурсами и описываемая в главе 10 при рассмотрении файлов. Второе новое средство называется многократным перехватом, а третье — окончательным или более точным повторным генерированием исключений. Два последних средства рассматриваются ниже.

Многократный перехват позволяет перехватывать два или более исключения одним оператором catch. Как пояснялось ранее, после оператора try можно (и даже принято) указывать два или более оператора catch. И хотя каждый блок оператора catch, как правило, содержит свою особую кодовую последовательность, нередко в двух или более блоках оператора catch выполняется одна и та же кодовая последовательность, несмотря на то, что в них перехватываются разные исключения. Вместо того чтобы перехватывать каждый тип исключения в отдельности, теперь можно воспользоваться единым блоком оператора catch для обработки исключений, не дублируя код.

Для организации многократного перехвата следует указать список исключений в одном операторе catch, разделив их типы оператором поразрядного ИЛИ. Каждый параметр многократного перехвата неявно указывается как final. (По желанию модификатор доступа final можно указать и явным образом, но это совсем не обязательно.) А поскольку каждый параметр многократного перехвата неявно указывается как final, то ему нельзя присвоить новое значение.

В приведенной ниже строке кода показывается, каким образом многократный перехват исключений ArithmeticException и ArraylndexOutOfBoundsException указывается в одном операторе catch.

catch(final ArithmeticException | ArraylndexOutOfBoundsException e) {

Ниже приведен краткий пример программы, демонстрирующий применение многократного перехвата исключений.

// Применение средства многократного перехвата исключений.
// Примечание: для компиляции этого кода требуется JDK 7
// или более поздняя версия данного комплекта,
class MultiCatch {
    public static void main(String args[]) {
        int a=88, b=0;
        int result;
        char chrs[] = { 'А', 'В', 'C' };

        for(int i=0; i < 2; i++)    {
            try {
                if (i == 0)
                    // сгенерировать исключение ArithmeticException
                    result = а / b;
                else
                    // сгенерировать исключение ArraylndexOutOfBoundsException
                    chrs[5] = 'X';
            }
            // В этом операторе catch организуется перехват обоих исключений,
            catch(ArithmeticException | ArraylndexOutOfBoundsException е) {
                System.out.println("Exception caught: " + e);
            }
        }

        System.out.println("After multi-catch.");
    }
}

В данном примере программы исключение ArithmeticException генерируется при попытке деления на нуль, а исключение ArraylndexOutOfBoundsException — при попытке обращения за границы массива chrs. Оба исключения перехватываются одним оператором catch.

Средство более точного повторного генерирования исключений ограничивает этот процесс лишь теми проверяемыми типами исключений, которые генерируются в соответствующем блоке try и не обрабатываются в предыдущем блоке оператора catch, а также относятся к подтипу или супертипу указываемого параметра. И хотя такая возможность требуется нечасто, ничто не мешает теперь воспользоваться ею в полной мере. А для организации окончательного повторного генерирования исключений параметр оператора catch должен быть, по существу, указан как final. Это означает, что ему нельзя присвоить новое значение в блоке catch. Он может быть указан как final явным образом, хотя это и не обязательно.

В стандартном пакете java. lang определены некоторые классы, представляющие стандартные исключения Java. Часть из них использовалась в предыдущих примерах программ. Наиболее часто встречаются исключения из подклассов стандартного класса RuntimeException. А поскольку пакет java. lang импортируется по умолчанию во все программы на Java, то исключения, производные от класса RuntimeException, становятся доступными автоматически. Их даже обязательно включать в список оператора throws. В терминологии языка Java такие исключения называют непроверяемыми, поскольку компилятор не проверяет, обрабатываются или генерируются подобные исключения в методе. Непроверяемые исключения, определенные в пакете java.lang, приведены в табл. 9.2, тогда как в табл. 9.3 — те исключения из пакета j ava. lang, которые следует непременно включать в список оператора throws при объявлении метода, если, конечно, в методе содержатся операторы, способные генерировать эти исключения, а их обработка не предусмотрена в теле метода. Такие исключения принято называть проверяемыми. В Java предусмотрен также ряд других исключений, определения которых содержатся в различных библиотеках классов. К их числу можно отнести упоминавшееся ранее исключение IOException.

Таблица 9.2. Непроверяемые исключения, определенные в пакете java.lang

Исключение Описание
ArithmeticException Арифметическая ошибка, например попытка деления на нуль
ArraylndexOutOfBoundsException Попытка обращения за границы массива
ArrayStoreException Попытка ввести в массив элемент, несовместимый с ним по типу
ClassCastException Недопустимое приведение типов
EnumConstNotPresentException Попытка использования нумерованного значения, которое не было определено ранее
IllegalArgumentException Недопустимый параметр при вызове метода
IllegalMonitorStateException Недопустимая операция контроля, например, ожидание разблокировки потока
IllegalStateException Недопустимое состояние среды выполнения или приложения
IllegalThreadStateException Запрашиваемая операция несовместима с текущим состоянием потока
IndexOutOfBoundsException Недопустимое значение индекса
NegativeArraySizeException Создание массива отрицательного размера
NullPointerException Недопустимое использование пустой ссылки
NumberFormatException Неверное преобразование символьной строки в число
SecurityException Попытка нарушить систему защиты
StringlndexOutOfBounds Попытка обращения к символьной строке за ее границами
TypeNotPresentException Неизвестный тип
UnsupportedOperationException Неподдерживаемая операция

Таблица 9.3. Проверяемые исключения, определенные в пакете java.lang

Исключение Описание
ClassNotFoundException Класс не найден
CloneNotSupportedException Попытка клонирования объекта, не реализующего интерфейс Cloneable
IllegalAccessException Доступ к классу запрещен
InstantiationException Попытка создания объекта абстрактного класса или интер¬фейса
InterruptedException Прерывание одного потока другим
NoSuchFieldException Требуемое поле не существует
NoSuchMethodException Требуемый метод не существует
ReflectiveOperationException Суперкласс исключений, связанных с рефлексией (добавлен в версии JDK 7)

Создание подклассов, производных от класса Exception

Несмотря на то что встроенные в Java исключения позволяют обрабатывать большинство ошибок, механизм обработки исключений не ограничивается только этими ошибками. В частности, можно создавать исключения для обработки потенциальных ошибок в прикладной программе. Создать исключение несложно. Для этого достаточно определить подкласс, производный от класса Exception, который, в свою очередь, является подклассом, порожденным классом Throwable. В создаваемый подкласс не обязательно включать реализацию каких-то методов. Сам факт существования такого подкласса позволяет использовать его в качестве исключения.

В классе Exception не определены новые методы. Он лишь наследует методы, предоставляемые классом Throwable. Таким образом, все исключения, включая и создаваемые вами, содержат методы класса Throwable. Конечно же, вы вольны переопределить в создаваемом вами классе один или несколько методов.

Ниже приведен пример, в котором создается исключение NonlntResultException. Оно генерируется в том случае, если результатом деления двух целых чисел является дробное число. В классе NonlntResultException содержатся два поля, предназначенные для хранения целых чисел, а также конструктор. В нем также переопределен метод toString(), что дает возможность выводить описание исключения с помощью метода println().

// Применение специально создаваемого исключения.
// создать исключение
class NonlntResultException extends Exception {
    int n;
    int d;

    NonlntResultException(int i, int j) {
        n = i;
        d = j;
    }

    public String toString()    {
        return "Result of " + n + " / " + d +
                " is non-integer.";
    }
}

class CustomExceptDemo {
    public static void main(String args[]) {

        // В массиве numer содержатся нечетные числа,
        int numer[] = { 4, 8, 15, 32, 64, 127, 256, 512 };
        int denom[] = { 2, 0, 4, 4, 0, 8 };

        for(int i=0; i<numer.length; i++)   {
            try {
                if((numer[i]%2) != 0)
                    throw new
                        NonlntResultException(numer[i], denom[i]);
                System.out.println(numer[i] + " / " +
                                   denom[i] + 11 is " +
                                   numer[i]/denom[i]);
            }
            catch (ArithmeticException exc) {
                // перехватить исключение
                System.out.println("Can11 divide by Zero!");
            }
            catch (ArraylndexOutOfBoundsException exc) {
                // перехватить исключение
                System.out.println("No matching element found.");
            }
            catch (NonlntResultException exc) {
                System.out.println(exc) ;
            }
        }
    }
}

Результат выполнения данной программы выглядит следующим образом:

4 / 2 is 2
Can't divide by Zero!
Result of 15 / 4 is non-integer.
32 / 4 is 8
Can't divide by Zero!
Result of 127 / 8 is non-integer.
No matching element found.
No matching element found.

Пример для опробования 9.1.
Добавление исключений в класс очереди

В этом проекте предстоит создать два класса исключении, которые будут использоваться классом очереди, разработанным в примере для опробования 8.1. Эти исключения должны указывать на переполнение и опустошение очереди, а генерировать их будут методы put() и get() соответственно. Ради простоты эти исключения добавляются в класс FixedQueue, но вы можете без труда внедрить их в любые другие классы очереди, разработанные в примере для опробования 8.1.

Последовательность действий

  1. Создайте файл QExcDemo.java.
  2. Определите следующие исключения в файле QExcDemo.java:
    /*
    Пример для опробования 9.1.
    Добавление обработчиков исключений в класс очереди.
    */
    // Исключение, указывающее на переполнение очереди,
    class QueueFullException extends Exception {
        int size;
    
        QueueFullException(int s) { size = s; }
    
        public String toString()    {
            return "nQueue is full. Maximum size is " + size;
        }
    }
    
    // Исключение, указывающее на опустошение очереди,
    class QueueEmptyException extends Exception {
        public String toString()    {
            return "nQueue is empty.";
        }
    }
    

    Исключение QueueFullException генерируется при попытке поместить элемент в уже заполненную очередь, а исключение QueueEmptyException — в ответ на попытку извлечь элемент из пустой очереди.

  3. Измените класс FixedQueue таким образом, чтобы при возникновении ошибки он генерировал исключение. Соответствующий код приведен ниже. Введите этот код в файл QExcDemo.java.
    // Класс, реализующий очередь фиксированного размера
    // для хранения символов.
    class FixedQueue implements ICharQ {
        private char q[]; // Массив для хранения элементов очереди,
        private int putloc, getloc; // Индексы размещения и извлечения
    
        // элементов очереди.
        // создать пустую очередь заданного размера
        public FixedQueue(int size) {
            q = new char[size+1]; // выделить память для очереди
            putloc = getloc = 0;
        }
    
        // поместить символ в очередь
        public void put(char ch)
        throws QueueFullException {
    
            if(putloc==q.length-1)
                throw new QueueFullException(q.length-1);
    
            putloc++;
            q[putloc] = ch;
        }
    
        // извлечь символ из очереди
        public char get()
        throws QueueEmptyException {
    
            if(getloc == putloc)
                throw new QueueEmptyException();
    
            getloc++;
            return q[getloc];
        }
    }
    

    Добавление исключений в класс FixedQueue выполняется в два этапа. Сначала в определении методов get() и put() указывается оператор throws с типом генерируемого исключения. А затем в этих методах организуется генерирование исключений при возникновении ошибок. Используя исключения, можно организовать обработку ошибок в вызывающей части программы наиболее рациональным способом. Как вы помните, в предыдущих версиях рассматриваемой здесь программы выводились только сообщения об ошибках. А генерирование исключений является более профессиональным подходом к разработке данной программы.

  4. Для опробования усовершенствованного класса FixedQueue введите в файл QExcDemo.java приведенный ниже исходный код класса QExcDemo.
    // Демонстрация исключений при обращении с очередью,
    class QExcDemo {
        public static void main(String args[])  {
            FixedQueue q = new FixedQueue(10);
            char ch;
            int i;
    
            try {
                // Переполнение очереди.
                for(i=0; i < 11; i++)   {
                    System.out.print("Attempting to store : " +
                                     (char) ('A' + i));
                    q.put((char) (fA' + i));
                    System.out.println(" - OK");
                }
                System.out.println();
            }
            catch (QueueFullException exc) {
                System.out.println(exc);
            }
            System.out.println();
    
            try {
                // Попытка извлечь символ из пустой очереди.
                for(i=0; i < 11; i++) {
                System.out.print("Getting next char: ");
                ch = q.get();
                System.out.println(ch);
                }
            }
            catch (QueueEmptyException exc) {
                System.out.println(exc);
            }
        }
    }
    
  5. Класс FixedQueue реализует интерфейс ICharQ, в котором определены методы get() и put(), и поэтому интерфейс ICharQ необходимо изменить таким образом, чтобы в нем отражалось наличие операторов throws. Ниже приведен видоизмененный соответственно код интерфейса ICharQ. Не забывайте о том, что он должен храниться в файле ICharQjava.
    // Интерфейс очереди для хранения символов с генерированием исключений,
    public interface ICharQ {
        // поместить символ в очередь
        void put(char ch) throws QueueFullException;
        // извлечь символ из очереди
        char get() throws QueueEmptyException;
    }
    
  6. Скомпилируйте сначала новую версию исходного файла IQChar. j ava, а затем исходный файл QExcDemo. java и запустите программу QExcDemo на выполнение. В итоге вы получите следующий результат ее выполнения:
    Attempting to store A - OK
    Attempting to store В - OK
    Attempting to store С - OK
    Attempting to store D - OK
    Attempting to store E - OK
    Attempting to store F - OK
    Attempting to store G - OK
    Attempting to store H - OK
    Attempting to store I - OK
    Attempting to store J - OK
    Attempting to store К
    Queue is full. Maximum size is 10
    
    Getting next char: A
    Getting next char: В
    Getting next char: С
    Getting next char: D
    Getting next char: E
    Getting next char: F
    Getting next char: G
    Getting next char: H
    Getting next char: I
    Getting next char: J
    Getting next char:
    Queue is empty.
    

Упражнение для самопроверки по материалу главы 9

  1. Какой класс находится на вершине иерархии исключений?
  2. Объясните вкратце, как пользоваться ключевыми словами try и catch?
  3. Какая ошибка допущена в приведенном ниже фрагменте кода?
    // ...
    vals[18] = 10;
    catch (ArraylndexOutOfBoundsException exc) {
        // обработать ошибку
    }
    
  4. Что произойдет, если исключение не будет перехвачено?
  5. Какая ошибка допущена в приведенном ниже фрагменте кода?
    class A extends Exception { ...
    class В extends А { ...
        // ...
    try {
        // ...
    }
    catch (A exc) { ... }
    catch (В exc) { ... }
    
  6. Может ли внутренний блок catch повторно генерировать исключение, которое будет обработано во внешнем блоке catch?
  7. Блок finally — последний фрагмент кода, выполняемый перед завершением программы. Верно или неверно? Обоснуйте свой ответ.
  8. Исключения какого типа необходимо явно объявлять с помощью оператора throws, включаемого в объявление метода?
  9. Какая ошибка допущена в приведенном ниже фрагменте кода?
    class MyClass { // ... }
    // ...
    throw new MyClass();
    
  10. Отвечая на вопрос 3 упражнения для самопроверки по материалу главы 6, вы создали класс Stack. Добавьте в него специальные исключения для реагирования на попытку поместить элемент в переполненный стек и извлечь элемент из пустого стека.
  11. Какими тремя способами можно сгенерировать исключение?
  12. Назовите два подкласса, производных непосредственно от класса Throwable.
  13. Что такое многократный перехват?
  14. Следует ли перехватывать в программе исключения типа Error?

1. Класс сканера

java.util.Scanner — это новая функция Java5. Мы можем получать вводимые пользователем данные через класс Scanner, а строку ввода — через методы next () и nextLine () класса Scanner. Обычно нам нужно использовать hasNext перед чтением Проверьте с помощью hasNextLine, есть ли еще входные данные.
Ниже приводится базовый синтаксис для создания объекта сканера:

Scanner s = new Scanner(System.in);

Разница между next () и nextLine ()

next():

1. Вы должны прочитать допустимые символы, прежде чем сможете завершить ввод.
2. Метод next () автоматически удаляет пробелы, встречающиеся перед вводом допустимых символов.
3. Только после ввода действительных символов пробелы, введенные после них, используются как разделители или терминаторы.
4. Next () не может получить строку с пробелами.

nextLine():

1. Возьмите Enter в качестве терминатора, что означает, что метод nextLine () возвращает все символы перед возвратом каретки.
2. Можно получить пустое поле.

Если вы хотите ввести данные типа int или float, он также поддерживается в классе Scanner, но лучше всего использовать метод hasNextXxx () для проверки перед вводом, а затем использовать nextXxx () для чтения:

import java.util.Scanner;

public class ScannerDemo {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        // Получаем данные с клавиатуры
        int i = 0;
        float f = 0.0f;
        System.out.print("Введите целое число:");
        if (scan.hasNextInt()) {
            // Определяем, является ли ввод целым числом
            i = scan.nextInt();
            // получаем целое число
            System.out.println("Целочисленные данные:" + i);
        } else {
            // Ввод неверной информации
            System.out.println("Введено не целое число!");
        }
        System.out.print("Введите десятичную дробь:");
        if (scan.hasNextFloat()) {
            // Определяем, является ли ввод десятичным
            f = scan.nextFloat();
            // получаем десятичную дробь
            System.out.println("Десятичные данные:" + f);
        } else {
            // Ввод неверной информации
            System.out.println("Ввод не десятичный!");
        }
        scan.close();
    }
}

Результат вышеупомянутой программы:

$ javac ScannerDemo.java
$ java ScannerDemo
Введите целое число:12
 Целочисленные данные:12
 Введите десятичное число:1.2
 Десятичные данные:1.2

2. Обработка исключений Java

Исключения — это некоторые ошибки в программе, но не все ошибки являются исключениями, и ошибок иногда можно избежать.
Чтобы понять, как работает обработка исключений Java, вам необходимо освоить следующие три типа исключений:

  • Нарушение исследования: наиболее репрезентативное отклонение от нормы исследованияИсключения, вызванные ошибками или проблемами пользователя, Программисты этого не предвидят. Например, при открытии несуществующего файла возникает исключение.Эти исключения нельзя просто игнорировать во время компиляции.
  • Исключение времени выполнения:Исключения времени выполнения — это исключения, которых программисты могут избежать.. В отличие от проверенных исключений, исключения времени выполнениямочьИгнорируется во время компиляции.
  • Ошибка: ошибка — это не исключение, а проблема, не зависящая от программиста. Ошибки в коде обычно игнорируются. Например, при переполнении стека возникает ошибка,Их нельзя проверить даже во время компиляции

Ноты:
1. Проверяемое исключение: компиляция не выполняется без обработки.
2. Непроверенное исключение: компиляцию можно передать без обработки, если она передается непосредственно в консоль.
3、Исключения времени выполнения: непроверенные исключения
4、Исключение не во время выполнения: проверенное исключение

2.1 Иерархия класса Exception

Все классы исключений являются подклассами, унаследованными от класса java.lang.Exception.
Класс исключения является подклассом класса Throwable. В дополнение к классу Exception,Throwable также имеет подкласс Error.
Программы на Java обычно не обнаруживают ошибок. Ошибки обычно возникают при серьезных сбоях, и они выходят за рамки программы Java.
Ошибка используется для обозначения ошибки, возникшей в среде выполнения.
Например, переполнение памяти JVM. обычно,Программа не восстановится после ошибки

Класс исключения имеет два основных подкласса: класс IOException и класс RuntimeException.

2.2 Встроенные классы исключений Java

Встроенные классы исключений Java имеют большинство обычно используемых отмеченных и непроверенных исключений. Язык Java определяет некоторые классы исключений в стандартном пакете java.lang. Подклассы стандартных классов исключений среды выполнения являются наиболее распространенными классами исключений.Поскольку пакет java.lang по умолчанию загружается во все программы Java, Таким образом, большинство исключений, унаследованных от класса исключений времени выполнения, можно использовать напрямую.

2.3 Исключения из улова

Используйте ключевые слова try и catch, чтобы поймать исключения. Блок кода try / catch размещается там, где может возникнуть исключение.
Вызывается код в блоке try / catchКод защиты, Синтаксис использования try / catch следующий:

try
{
   // код
}catch(ExceptionName e1)
{
   // Поймать блок
}

Оператор Catch содержит объявление типа исключения, которое необходимо перехватить. Когда в защищенном блоке кода возникает исключение, проверяется блок catch после попытки.
Если возникшее исключение содержится в блоке catch,Исключение будет передано в блок catch, что аналогично передаче параметра методу.

2.4 Множественные блоки захвата

Блок кода попытки, за которым следует несколько блоков кода перехвата, называется множественным перехватом.
Синтаксис блока множественного захвата следующий:

try{
   // код
}catch(Тип исключения1  Ненормальное имя переменной1){
  // код
}catch(Тип исключения2  Ненормальное имя переменной2){
  // код
}catch(Тип исключения2  Ненормальное имя переменной2){
  // код
}

Приведенный выше фрагмент кода содержит 3 блока catch.
Вы можете добавить любое количество блоков catch после оператора try.
Если в коде защиты возникает исключение, исключение переходит в первый блок catch.
Если тип данных вызванного исключения соответствует ExceptionType1, оно будет перехвачено здесь.
Если он не совпадает, он будет передан во второй блок catch.
Итак, пока исключение не будет перехвачено или не пройдёт все блоки catch.

2.5 броска / броска ключевые слова:

Если метод не обнаруживает проверенное исключение,Затем метод должен быть объявлен с использованием ключевого слова throws. Ключевое слово throws помещается в конец сигнатуры метода.
также может использовать ключевое слово throw для создания исключения, независимо от того, создано ли оно заново или только что.
Следующее объявление метода вызывает исключение RemoteException:

import java.io.*;
public class className
{
  public void deposit(double amount) throws RemoteException
  {
    // Method implementation
    throw new RemoteException();
  }
  //Remainder of class definition
}

Метод может объявить, что генерирует несколько исключений, разделенных запятыми.

2.6 наконец ключевое слово

Ключевое слово finally используется для создания блока кода, который выполняется после блока кода try.
Независимо от того, возникает ли исключение, код в блоке кода finally всегда будет выполняться
В блоке кода finally вы можете запускать типы очистки и другие операторы завершения.

Обратите внимание на следующее:

  • Улов не может существовать независимо от попытки.
  • Добавлять блок finally после try / catch не обязательно.
  • После кода попытки не может быть ни блока catch, ни блока finally.
  • Между блоками try, catch и finally нельзя добавить код.

2.7 Объявление пользовательских исключений

Вы можете настроить исключения в Java. При написании собственного класса исключений необходимо учитывать следующие моменты.

Все исключения должны быть подклассом Throwable.
Если вы хотите написать проверенный класс исключения, вам необходимо унаследовать класс Exception.
Если вы хотите написать класс исключения времени выполнения, вам необходимо унаследовать класс RuntimeException.

Вы можете определить свой собственный класс исключения следующим образом:

class MyException extends Exception{
...
}

Класс исключения, созданный путем наследования только класса Exception, является проверенным классом исключения.

Пример
Следующий пример представляет собой симуляцию банковского счета. Идентификация завершается по номеру банковской карты, и можно выполнять операции по внесению и снятию денег.
Код файла InsfficientFundsException.java:

// Имя файла InsfficientFundsException.java
import java.io.*;

// Пользовательский класс исключения, наследующий класс исключения
public class InsufficientFundsException extends Exception
{
  // Сумма здесь используется для хранения денег, которые отсутствуют при возникновении исключения (когда снято больше денег, чем на балансе)
  private double amount; // приватизация, полученная с помощью getAmount ()
  public InsufficientFundsException(double amount)
  {
    this.amount = amount;
  } 
  public double getAmount() 
  {
    return amount; 
  }
}

Чтобы показать, как использовать наш настраиваемый класс исключений, включите метод remove () в класс CheckingAccount ниже, чтобы вызвать исключение ShouldFundsException.
Код файла CheckingAccount.java:

// Имя файла CheckingAccount.java
import java.io.*;

// Такой симулированный банковский счет
public class CheckingAccount
{
  // баланс - это баланс, number - номер карты
   private double balance;
   private int number;
   public CheckingAccount(int number)
   {
      this.number = number;
   }
  // Метод: внести деньги
   public void deposit(double amount)
   {
      balance += amount;
   }
  // Метод: вывод денег
   public void withdraw(double amount) throws
                              InsufficientFundsException
   {
      if(amount <= balance)
      {
         balance -= amount;
      }
      else
      {
         double needs = amount - balance;
         throw new InsufficientFundsException(needs);
      }
   }
  // Метод: вернуть баланс
   public double getBalance()
   {
      return balance;
   }
  // Метод: вернуть номер карты
   public int getNumber()
   {
      return number;
   }
}

Следующая программа BankDemo демонстрирует, как вызвать методы deposit () и remove () класса CheckingAccount.
Код файла BankDemo.java:

// Имя файла BankDemo.java
public class BankDemo
{
   public static void main(String [] args)
   {
      CheckingAccount c = new CheckingAccount(101);
      System.out.println("Depositing $500...");
      c.deposit(500.00);
      try
      {
         System.out.println("nWithdrawing $100...");
         c.withdraw(100.00);
         System.out.println("nWithdrawing $600...");
         c.withdraw(600.00);
      }catch(InsufficientFundsException e)
      {
         System.out.println("Sorry, but you are short $"
                                  + e.getAmount());
         e.printStackTrace();
      }
    }
}

Скомпилируйте указанные выше три файла и запустите программу BankDemo, результаты будут следующими:

Depositing $500...

Withdrawing $100...

Withdrawing $600...
Sorry, but you are short $200.0
InsufficientFundsException
        at CheckingAccount.withdraw(CheckingAccount.java:25)
        at BankDemo.main(BankDemo.java:13)

2.8 Общее исключение

В Java определены два типа исключений и ошибок.

  • Исключения JVM (виртуальная машина Java): исключения или ошибки, создаваемые JVM. Например: класс NullPointerException, класс ArrayIndexOutOfBoundsException, класс ClassCastException.
  • Исключения на уровне программы: исключения, создаваемые программами или программами API. Например, класс IllegalArgumentException, класс IllegalStateException.

2.9 Ненормальное использование может соответствовать следующим принципам:

1: Когда текущий метод перезаписывается, перезаписывающий метод должен генерировать то же исключение или подкласс исключения;
2: используйте оператор try-catch для перехвата исключения в текущем объявлении метода;
3: если родительский класс генерирует несколько исключений, метод переопределения должен генерировать подмножество этих исключений и не может генерировать новые исключения.

2.10 Сводка исключений:


Как показано на рисунке, все исключения и ошибки наследуются от класса Throwable, что означает, что все исключения являются объектом.
примерно разделите исключение на две части:

1. Ошибка — ошибка: относится к ошибке, которую программа не может обработать, и представляет собой серьезную ошибку, которая возникает во время работы приложения. Например, OutOfMemoryError во время работы jvm и занятый порт во время программирования Socket — это ошибки, которые программа не может обработать.

2. Exception — исключение: исключения можно разделить на исключения времени выполнения и исключения компиляции.
(1) Исключение времени выполнения: RuntimeException и другие исключения. Этот тип исключения не будет обнаружен компилятором при написании кода, и его не нужно перехватывать, но программист также может поймать и выбросить по мере необходимости. Общие исключения RUNtimeExceptions включают в себя: NullpointException (исключение нулевого указателя), ClassCastException (исключение преобразования типа), IndexOutOfBoundsException (исключение массива вне границ) и т. Д.
(2) Исключение компиляции: исключения, отличные от RuntimeException. Компилятор предложит вам зафиксировать этот тип исключения во время компиляции. Если вы не зафиксируете его, произойдет ошибка компиляции. Общие исключения компиляции включают: IOException (исключение передачи потока), SQLException (исключение операции с базой данных) и т. Д.

3. Механизм Java для обработки исключений: выдача исключений и перехват исключений Исключение, которое может перехватить метод, должно быть исключением, сгенерированным где-то кодом Java. вообще говоря,Исключения всегда сначала генерируются, а затем перехватываются

4. Разница между броском и броском:

public void test() throws Exception {
    throw new Exception();
}

Разницу между ними ясно видно из приведенного выше кода.. Throws означает, что объявление метода может вызвать исключение, а throw означает, что здесь выбрасывается определенное исключение (это может быть обычное наследование Exception, или это может быть класс исключения, предоставленный самой Java).

5. Давайте посмотрим, как перехватывать исключения:
(1) Прежде всего, java использует блок кода try-catch или try-catch-finally для захвата исключения, программа захватит код в блоке кода try, и если он улавливает исключение, он перехватит обработку блока кода. Если есть finally, выполните код в finally после обработки catch. Однако есть две проблемы:
а. Посмотрите на следующий код:

try{
    // Код для записи
}catch(Exception e){
    System.out.println("catch is begin");
    return 1 ;
}finally{
     System.out.println("finally is begin");
}

Есть отдача в улове, исполнится окончательно? Ответ — да, результат выполнения приведенного выше кода:

catch is begin
finally is begin

То есть сначала будет выполнен код в catch, затем код в finally будет выполнен перед возвратом1;
б. Посмотрите на следующий код:

try{
   // Код для записи    
}catch(Exception e){
    System.out.println("catch is begin");
    return 1 ;
}finally{
     System.out.println("finally is begin");
     return 2 ;
}

В коде b выходной результат такой же, как у a, но возвращается return 2;Причина очевидна, то есть возврат был выполнен после finally, поэтому возврат в catch не будет выполнен.Другими словами, finally всегда будет выполняться перед возвратом улова. (Это вопрос, который часто задают в интервью!)

6. Не должно быть удобно захватывать исключения и объединять несколько исключений в одно исключение для захвата, например исключения ввода-вывода и исключения SQL, чтобы два совершенно разных исключения обрабатывались отдельно!И при обработке исключений в catch не просто используйте e.printStackTrace (), а обрабатывайте их подробно. Например, сведения о печати с консоли или записи журнала.

Примечание. Разница между исключениями и ошибками: исключения могут обрабатываться самой программой, но ошибки не могут быть обработаны.

Язык Java определяет некоторые классы исключений в стандартном пакете java.lang. Подклассы стандартных классов исключений среды выполнения являются наиболее распространенными классами исключений. Поскольку пакет java.lang загружается во все программы Java по умолчанию, большинство исключений, унаследованных от классов исключений времени выполнения, можно использовать напрямую.
Примечание: finally может не выполняться, например, если есть оператор для выхода из системы в блоке catch System.exit (-1); finally не будет выполнен

Из:http://www.runoob.com/java/java-exceptions.html

in the case that I want to throw an exception when the wrong type of data type is entered, how can I do this with IllegalArgumentException?

if(row < 1) {
        row = 1;
    }
    if(row > 5) {
        row = 5;
    }
    if (row != int) {
        throw new IllegalArgumentException("Please enter appropriate integer.");
    }
    System.out.print("Specify red value (0-255): ");
    int red = console.nextInt();
    if(red < 0) {
        red = 0;
    }
    if(red > 255) {
        red = 255;
    }
    if (red != int){
        throw new IllegalArgumentException("Please enter appropriate integer.");
    }
    System.out.print("Specify green value (0-255): ");
    int green = console.nextInt();
    if(green < 0) {
        green = 0;
    } 
    if(green > 255) {
        green = 255;
    }
    if (green != int){
        throw new IllegalArgumentException("Please enter appropriate integer.");
    }
    System.out.print("Specify blue value (0-255): ");
    int blue = console.nextInt();
    if(blue < 0) {
        blue = 0;
    }
    if(blue > 255) {
        blue = 255;
    } 
    if (green != int){
        throw new IllegalArgumentException("Please enter appropriate integer.");
    }

My main problem is with the «!= int» part. I know for a fact that this is not right, but I am not sure what else to use. Using an else statement will not work either. If someone were to enter a double, string, or boolean input into the scanner instead of an integer, how could I throw an exception for this? I have to do this for an assignment, and they specifically said that I need to use a throw exception for this. Thanks everyone in advance!

asked Jun 17, 2018 at 8:02

Shilpa Kancharla's user avatar

1

(red != int)

What are you trying to do

Let me come to the question title "Throwing exception for wrong data types". Well if this is the actual question then you dont need to do anything the line

int red = console.nextInt();

will automatically throw an exception if the data type is anything other than an Integer.

answered Jun 17, 2018 at 8:25

Sundeep's user avatar

1

  1. Making them new method for example.

    private void inputColorDetails(){
    if(row < 1) {
            row = 1;
        }
        if(row > 5) {
            row = 5;
        }
        if (row != int) {
            throw new IllegalArgumentException("Please enter appropriate integer.");
        }
        System.out.print("Specify red value (0-255): ");
        int red = console.nextInt();
        if(red < 0) {
            red = 0;
        }
        if(red > 255) {
            red = 255;
        }
        if (red != int){
            throw new IllegalArgumentException("Please enter appropriate integer.");
        }
        System.out.print("Specify green value (0-255): ");
        int green = console.nextInt();
        if(green < 0) {
            green = 0;
        } 
        if(green > 255) {
            green = 255;
        }
        if (green != int){
            throw new IllegalArgumentException("Please enter appropriate integer.");
        }
        System.out.print("Specify blue value (0-255): ");
        int blue = console.nextInt();
        if(blue < 0) {
            blue = 0;
        }
        if(blue > 255) {
            blue = 255;
        } 
        if (green != int){
            throw new IllegalArgumentException("Please enter appropriate integer.");
        }
    }
    
  2. Call them in main as try catch.

    private void Main(){
    try {
        inputColorDetails();
    } catch (NumberFormatException e) {
        System.out.prinln(e.getMessage());
    }  }
    

answered Jun 17, 2018 at 8:55

Ticherhaz FreePalestine's user avatar

You could look at using the «instanceof» keyword or Class.isInstance()

var instanceof Integer
Integer.class.isInstance(var)

As JB Nizet noted, the nextInt() method only returns an integer though, so this check shouldn’t be necessary.

To get any input and check it afterwards you could do

int color;
String input = console.next();
try {
    color = Integer.parseInt(input)
} catch (NumberFormatException e) {
    throw new IllegalArgumentException("Input "" + input + "" was not an integer");
}

(Code off the top of my head, please correct me if I’m wrong)

answered Jun 17, 2018 at 8:10

Tavi Kohn's user avatar

При вводе нескольких значений с консоли выходит данная ошибка.

import java.io.IOException;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws IOException {
       Scanner scanner = new Scanner(System.in);
       int c = Integer.parseInt(scanner.nextLine());
       int b = Integer.parseInt(scanner.nextLine());
        System.out.println(c+b);
    }
}

1
1
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
    at java.base/java.lang.Integer.parseInt(Integer.java:678)
    at java.base/java.lang.Integer.parseInt(Integer.java:784)
    at Main.main(Main.java:9)


  • Вопрос задан

    более года назад

  • 300 просмотров

Добрый день.
Проблема заключается в следующем:
Вы сперва с вводите первое число и нажимаете на перевод строки (Enter).
Когда вы нажимаете на перевод строки срабатывает ввод числа b, который и принимает собственно говоря знак перевода строки и так как он не является числом, то выбрасывается исключение.
Чтобы этого не было:

int c = Integer.parseInt(scanner.nextLine());
Scanner.nextline();
int b = Integer.parseInt(scanner.nextLine());

И как отметил коллега — используйте nextInt() вместо nextLine()
Вот, аналогичная проблема — https://stackoverflow.com/questions/13102045/scann…

Пригласить эксперта

Если используете класс Scanner, то для считывания чисел из потока удобнее использовать пару методов hasNextInt и nextInt.

Возможно в вашем случае первый вызов scanner.nextLine() вычитал весь поток и при втором вызове вернулась пустая строка.

В ошибке все написано. Ты пытаешься пустую строку привести к числу


  • Показать ещё
    Загружается…

Сбер

Екатеринбург

До 160 000 ₽

24 июн. 2023, в 23:21

5000 руб./за проект

24 июн. 2023, в 21:49

1000 руб./за проект

24 июн. 2023, в 18:21

30000 руб./за проект

Минуточку внимания

1. Класс сканера

java.util.Scanner — это новая функция Java5. Мы можем получать вводимые пользователем данные через класс Scanner, а строку ввода — через методы next () и nextLine () класса Scanner. Обычно нам нужно использовать hasNext перед чтением Проверьте с помощью hasNextLine, есть ли еще входные данные.
Ниже приводится базовый синтаксис для создания объекта сканера:

Scanner s = new Scanner(System.in);

Разница между next () и nextLine ()

next():

1. Вы должны прочитать допустимые символы, прежде чем сможете завершить ввод.
2. Метод next () автоматически удаляет пробелы, встречающиеся перед вводом допустимых символов.
3. Только после ввода действительных символов пробелы, введенные после них, используются как разделители или терминаторы.
4. Next () не может получить строку с пробелами.

nextLine():

1. Возьмите Enter в качестве терминатора, что означает, что метод nextLine () возвращает все символы перед возвратом каретки.
2. Можно получить пустое поле.

Если вы хотите ввести данные типа int или float, он также поддерживается в классе Scanner, но лучше всего использовать метод hasNextXxx () для проверки перед вводом, а затем использовать nextXxx () для чтения:

import java.util.Scanner;

public class ScannerDemo {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        // Получаем данные с клавиатуры
        int i = 0;
        float f = 0.0f;
        System.out.print("Введите целое число:");
        if (scan.hasNextInt()) {
            // Определяем, является ли ввод целым числом
            i = scan.nextInt();
            // получаем целое число
            System.out.println("Целочисленные данные:" + i);
        } else {
            // Ввод неверной информации
            System.out.println("Введено не целое число!");
        }
        System.out.print("Введите десятичную дробь:");
        if (scan.hasNextFloat()) {
            // Определяем, является ли ввод десятичным
            f = scan.nextFloat();
            // получаем десятичную дробь
            System.out.println("Десятичные данные:" + f);
        } else {
            // Ввод неверной информации
            System.out.println("Ввод не десятичный!");
        }
        scan.close();
    }
}

Результат вышеупомянутой программы:

$ javac ScannerDemo.java
$ java ScannerDemo
Введите целое число:12
 Целочисленные данные:12
 Введите десятичное число:1.2
 Десятичные данные:1.2

2. Обработка исключений Java

Исключения — это некоторые ошибки в программе, но не все ошибки являются исключениями, и ошибок иногда можно избежать.
Чтобы понять, как работает обработка исключений Java, вам необходимо освоить следующие три типа исключений:

  • Нарушение исследования: наиболее репрезентативное отклонение от нормы исследованияИсключения, вызванные ошибками или проблемами пользователя, Программисты этого не предвидят. Например, при открытии несуществующего файла возникает исключение.Эти исключения нельзя просто игнорировать во время компиляции.
  • Исключение времени выполнения:Исключения времени выполнения — это исключения, которых программисты могут избежать.. В отличие от проверенных исключений, исключения времени выполнениямочьИгнорируется во время компиляции.
  • Ошибка: ошибка — это не исключение, а проблема, не зависящая от программиста. Ошибки в коде обычно игнорируются. Например, при переполнении стека возникает ошибка,Их нельзя проверить даже во время компиляции

Ноты:
1. Проверяемое исключение: компиляция не выполняется без обработки.
2. Непроверенное исключение: компиляцию можно передать без обработки, если она передается непосредственно в консоль.
3、Исключения времени выполнения: непроверенные исключения
4、Исключение не во время выполнения: проверенное исключение

2.1 Иерархия класса Exception

Все классы исключений являются подклассами, унаследованными от класса java.lang.Exception.
Класс исключения является подклассом класса Throwable. В дополнение к классу Exception,Throwable также имеет подкласс Error.
Программы на Java обычно не обнаруживают ошибок. Ошибки обычно возникают при серьезных сбоях, и они выходят за рамки программы Java.
Ошибка используется для обозначения ошибки, возникшей в среде выполнения.
Например, переполнение памяти JVM. обычно,Программа не восстановится после ошибки

Класс исключения имеет два основных подкласса: класс IOException и класс RuntimeException.

2.2 Встроенные классы исключений Java

Встроенные классы исключений Java имеют большинство обычно используемых отмеченных и непроверенных исключений. Язык Java определяет некоторые классы исключений в стандартном пакете java.lang. Подклассы стандартных классов исключений среды выполнения являются наиболее распространенными классами исключений.Поскольку пакет java.lang по умолчанию загружается во все программы Java, Таким образом, большинство исключений, унаследованных от класса исключений времени выполнения, можно использовать напрямую.

2.3 Исключения из улова

Используйте ключевые слова try и catch, чтобы поймать исключения. Блок кода try / catch размещается там, где может возникнуть исключение.
Вызывается код в блоке try / catchКод защиты, Синтаксис использования try / catch следующий:

try
{
   // код
}catch(ExceptionName e1)
{
   // Поймать блок
}

Оператор Catch содержит объявление типа исключения, которое необходимо перехватить. Когда в защищенном блоке кода возникает исключение, проверяется блок catch после попытки.
Если возникшее исключение содержится в блоке catch,Исключение будет передано в блок catch, что аналогично передаче параметра методу.

2.4 Множественные блоки захвата

Блок кода попытки, за которым следует несколько блоков кода перехвата, называется множественным перехватом.
Синтаксис блока множественного захвата следующий:

try{
   // код
}catch(Тип исключения1  Ненормальное имя переменной1){
  // код
}catch(Тип исключения2  Ненормальное имя переменной2){
  // код
}catch(Тип исключения2  Ненормальное имя переменной2){
  // код
}

Приведенный выше фрагмент кода содержит 3 блока catch.
Вы можете добавить любое количество блоков catch после оператора try.
Если в коде защиты возникает исключение, исключение переходит в первый блок catch.
Если тип данных вызванного исключения соответствует ExceptionType1, оно будет перехвачено здесь.
Если он не совпадает, он будет передан во второй блок catch.
Итак, пока исключение не будет перехвачено или не пройдёт все блоки catch.

2.5 броска / броска ключевые слова:

Если метод не обнаруживает проверенное исключение,Затем метод должен быть объявлен с использованием ключевого слова throws. Ключевое слово throws помещается в конец сигнатуры метода.
также может использовать ключевое слово throw для создания исключения, независимо от того, создано ли оно заново или только что.
Следующее объявление метода вызывает исключение RemoteException:

import java.io.*;
public class className
{
  public void deposit(double amount) throws RemoteException
  {
    // Method implementation
    throw new RemoteException();
  }
  //Remainder of class definition
}

Метод может объявить, что генерирует несколько исключений, разделенных запятыми.

2.6 наконец ключевое слово

Ключевое слово finally используется для создания блока кода, который выполняется после блока кода try.
Независимо от того, возникает ли исключение, код в блоке кода finally всегда будет выполняться
В блоке кода finally вы можете запускать типы очистки и другие операторы завершения.

Обратите внимание на следующее:

  • Улов не может существовать независимо от попытки.
  • Добавлять блок finally после try / catch не обязательно.
  • После кода попытки не может быть ни блока catch, ни блока finally.
  • Между блоками try, catch и finally нельзя добавить код.

2.7 Объявление пользовательских исключений

Вы можете настроить исключения в Java. При написании собственного класса исключений необходимо учитывать следующие моменты.

Все исключения должны быть подклассом Throwable.
Если вы хотите написать проверенный класс исключения, вам необходимо унаследовать класс Exception.
Если вы хотите написать класс исключения времени выполнения, вам необходимо унаследовать класс RuntimeException.

Вы можете определить свой собственный класс исключения следующим образом:

class MyException extends Exception{
...
}

Класс исключения, созданный путем наследования только класса Exception, является проверенным классом исключения.

Пример
Следующий пример представляет собой симуляцию банковского счета. Идентификация завершается по номеру банковской карты, и можно выполнять операции по внесению и снятию денег.
Код файла InsfficientFundsException.java:

// Имя файла InsfficientFundsException.java
import java.io.*;

// Пользовательский класс исключения, наследующий класс исключения
public class InsufficientFundsException extends Exception
{
  // Сумма здесь используется для хранения денег, которые отсутствуют при возникновении исключения (когда снято больше денег, чем на балансе)
  private double amount; // приватизация, полученная с помощью getAmount ()
  public InsufficientFundsException(double amount)
  {
    this.amount = amount;
  } 
  public double getAmount() 
  {
    return amount; 
  }
}

Чтобы показать, как использовать наш настраиваемый класс исключений, включите метод remove () в класс CheckingAccount ниже, чтобы вызвать исключение ShouldFundsException.
Код файла CheckingAccount.java:

// Имя файла CheckingAccount.java
import java.io.*;

// Такой симулированный банковский счет
public class CheckingAccount
{
  // баланс - это баланс, number - номер карты
   private double balance;
   private int number;
   public CheckingAccount(int number)
   {
      this.number = number;
   }
  // Метод: внести деньги
   public void deposit(double amount)
   {
      balance += amount;
   }
  // Метод: вывод денег
   public void withdraw(double amount) throws
                              InsufficientFundsException
   {
      if(amount <= balance)
      {
         balance -= amount;
      }
      else
      {
         double needs = amount - balance;
         throw new InsufficientFundsException(needs);
      }
   }
  // Метод: вернуть баланс
   public double getBalance()
   {
      return balance;
   }
  // Метод: вернуть номер карты
   public int getNumber()
   {
      return number;
   }
}

Следующая программа BankDemo демонстрирует, как вызвать методы deposit () и remove () класса CheckingAccount.
Код файла BankDemo.java:

// Имя файла BankDemo.java
public class BankDemo
{
   public static void main(String [] args)
   {
      CheckingAccount c = new CheckingAccount(101);
      System.out.println("Depositing $500...");
      c.deposit(500.00);
      try
      {
         System.out.println("nWithdrawing $100...");
         c.withdraw(100.00);
         System.out.println("nWithdrawing $600...");
         c.withdraw(600.00);
      }catch(InsufficientFundsException e)
      {
         System.out.println("Sorry, but you are short $"
                                  + e.getAmount());
         e.printStackTrace();
      }
    }
}

Скомпилируйте указанные выше три файла и запустите программу BankDemo, результаты будут следующими:

Depositing $500...

Withdrawing $100...

Withdrawing $600...
Sorry, but you are short $200.0
InsufficientFundsException
        at CheckingAccount.withdraw(CheckingAccount.java:25)
        at BankDemo.main(BankDemo.java:13)

2.8 Общее исключение

В Java определены два типа исключений и ошибок.

  • Исключения JVM (виртуальная машина Java): исключения или ошибки, создаваемые JVM. Например: класс NullPointerException, класс ArrayIndexOutOfBoundsException, класс ClassCastException.
  • Исключения на уровне программы: исключения, создаваемые программами или программами API. Например, класс IllegalArgumentException, класс IllegalStateException.

2.9 Ненормальное использование может соответствовать следующим принципам:

1: Когда текущий метод перезаписывается, перезаписывающий метод должен генерировать то же исключение или подкласс исключения;
2: используйте оператор try-catch для перехвата исключения в текущем объявлении метода;
3: если родительский класс генерирует несколько исключений, метод переопределения должен генерировать подмножество этих исключений и не может генерировать новые исключения.

2.10 Сводка исключений:


Как показано на рисунке, все исключения и ошибки наследуются от класса Throwable, что означает, что все исключения являются объектом.
примерно разделите исключение на две части:

1. Ошибка — ошибка: относится к ошибке, которую программа не может обработать, и представляет собой серьезную ошибку, которая возникает во время работы приложения. Например, OutOfMemoryError во время работы jvm и занятый порт во время программирования Socket — это ошибки, которые программа не может обработать.

2. Exception — исключение: исключения можно разделить на исключения времени выполнения и исключения компиляции.
(1) Исключение времени выполнения: RuntimeException и другие исключения. Этот тип исключения не будет обнаружен компилятором при написании кода, и его не нужно перехватывать, но программист также может поймать и выбросить по мере необходимости. Общие исключения RUNtimeExceptions включают в себя: NullpointException (исключение нулевого указателя), ClassCastException (исключение преобразования типа), IndexOutOfBoundsException (исключение массива вне границ) и т. Д.
(2) Исключение компиляции: исключения, отличные от RuntimeException. Компилятор предложит вам зафиксировать этот тип исключения во время компиляции. Если вы не зафиксируете его, произойдет ошибка компиляции. Общие исключения компиляции включают: IOException (исключение передачи потока), SQLException (исключение операции с базой данных) и т. Д.

3. Механизм Java для обработки исключений: выдача исключений и перехват исключений Исключение, которое может перехватить метод, должно быть исключением, сгенерированным где-то кодом Java. вообще говоря,Исключения всегда сначала генерируются, а затем перехватываются

4. Разница между броском и броском:

public void test() throws Exception {
    throw new Exception();
}

Разницу между ними ясно видно из приведенного выше кода.. Throws означает, что объявление метода может вызвать исключение, а throw означает, что здесь выбрасывается определенное исключение (это может быть обычное наследование Exception, или это может быть класс исключения, предоставленный самой Java).

5. Давайте посмотрим, как перехватывать исключения:
(1) Прежде всего, java использует блок кода try-catch или try-catch-finally для захвата исключения, программа захватит код в блоке кода try, и если он улавливает исключение, он перехватит обработку блока кода. Если есть finally, выполните код в finally после обработки catch. Однако есть две проблемы:
а. Посмотрите на следующий код:

try{
    // Код для записи
}catch(Exception e){
    System.out.println("catch is begin");
    return 1 ;
}finally{
     System.out.println("finally is begin");
}

Есть отдача в улове, исполнится окончательно? Ответ — да, результат выполнения приведенного выше кода:

catch is begin
finally is begin

То есть сначала будет выполнен код в catch, затем код в finally будет выполнен перед возвратом1;
б. Посмотрите на следующий код:

try{
   // Код для записи    
}catch(Exception e){
    System.out.println("catch is begin");
    return 1 ;
}finally{
     System.out.println("finally is begin");
     return 2 ;
}

В коде b выходной результат такой же, как у a, но возвращается return 2;Причина очевидна, то есть возврат был выполнен после finally, поэтому возврат в catch не будет выполнен.Другими словами, finally всегда будет выполняться перед возвратом улова. (Это вопрос, который часто задают в интервью!)

6. Не должно быть удобно захватывать исключения и объединять несколько исключений в одно исключение для захвата, например исключения ввода-вывода и исключения SQL, чтобы два совершенно разных исключения обрабатывались отдельно!И при обработке исключений в catch не просто используйте e.printStackTrace (), а обрабатывайте их подробно. Например, сведения о печати с консоли или записи журнала.

Примечание. Разница между исключениями и ошибками: исключения могут обрабатываться самой программой, но ошибки не могут быть обработаны.

Язык Java определяет некоторые классы исключений в стандартном пакете java.lang. Подклассы стандартных классов исключений среды выполнения являются наиболее распространенными классами исключений. Поскольку пакет java.lang загружается во все программы Java по умолчанию, большинство исключений, унаследованных от классов исключений времени выполнения, можно использовать напрямую.
Примечание: finally может не выполняться, например, если есть оператор для выхода из системы в блоке catch System.exit (-1); finally не будет выполнен

Из:http://www.runoob.com/java/java-exceptions.html

  • Ошибка ввода вывода эксель
  • Ошибка вебасто f03 что означает
  • Ошибка ввода вывода файла pdf
  • Ошибка вебасто f02 как сбросить ошибку
  • Ошибка ввода вывода торрент qbittorrent