Перейти к содержимому

Illegalargumentexception что это

  • автор:

Lang illegalargumentexception как исправить java

IllegalArgumentException — это исключение, которое генерируется при передаче некорректных аргументов методу. Для исправления этой ошибки необходимо определить, какой метод вызывает исключение, и проанализировать передаваемые ему аргументы. Проверьте, что передаваемые значения соответствуют ожидаемым типам данных и допустимым диапазонам значений.

Например, если исключение IllegalArgumentException возникает при вызове метода Integer.parseInt() , проверьте, что передаваемая строка содержит только допустимые символы для целого числа, а также что значение входит в допустимый диапазон значений для типа int

Вот пример кода, который может вызвать IllegalArgumentException при передаче неверного аргумента:

// вызов метода Integer.parseInt() с некорректной строкой int value = Integer.parseInt("abc"); 

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

String str = "123"; int value = Integer.parseInt(str); 

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

Чем IllegalArgumentException лучше чем NullPointerException?

Речь здесь идет о выборе подхода к обработке ошибки, когда пользователь передал в non-nullable параметр значение null .

Технически, оба этих исключения unchecked, оба из стандартной библиотеки, и особой разницы нет.

Однако семантически эти исключения отличаются. NullPointerException говорит пользователю о попытке обратиться к членам класса через null-ссылку. Это лишь техническое описание, без информации для пользователя о логике программы. IllegalArgumentException , напротив, явно говорит о недопустимом значении аргумента – это понятная для пользователя информация.

Семантическая разница иногда проявляется и технически. Например, в обработчиках исключений некоторых фреймворков именно IllegalArgumentException превращается в HTTP-ответ с кодом 400 Bad Request, в то время как NPE остается общим кодом «неизвестной ошибки» 500 Internal Server Error.

Кроме того, чтобы выбросить NullPointerException не требуется явного кода обработки null . Остается неизвестным, ожидаемо ли в этом случае исключение, или разработчик попросту забыл добавить корректную обработку.

Явная обработка null и выброс IllegalArgumentException для пользователя кода будет служить документацией, а сообщение об ошибке в аргументе его конструктора внесет еще больше ясности.

Illegalargumentexception что это

Создает новое исключение с указанной причиной и сообщением детали (cause==null ? null : cause.toString()) (который обычно содержит класс и сообщение детали cause).

Сводка метода

Методы java.lang унаследованный от класса. Throwable

Методы java.lang унаследованный от класса. Объект

Деталь конструктора

IllegalArgumentException
public IllegalArgumentException()

Конструкции IllegalArgumentException без сообщения детали.

IllegalArgumentException

Конструкции IllegalArgumentException с указанным сообщением детали.

IllegalArgumentException
public IllegalArgumentException(String message, Throwable cause)

Создает новое исключение с указанным сообщением детали и причиной. Отметьте что сообщение детали, связанное с cause автоматически не включается в сообщение детали этого исключения.

IllegalArgumentException
public IllegalArgumentException(Throwable cause)

Создает новое исключение с указанной причиной и сообщением детали (cause==null ? null : cause.toString()) (который обычно содержит класс и сообщение детали cause). Этот конструктор полезен для исключений, которые являются немного больше чем обертки для другого throwables (например, PrivilegedActionException ).

Платформа Java™
Стандарт Эд. 7

Представьте ошибку или функцию
Для дальнейшей ссылки API и документации разработчика, см. Java Документация SE . Та документация содержит более подробные, предназначенные разработчиком описания, с концептуальными краткими обзорами, определениями сроков, обходных решений, и рабочих примеров кода.
Авторское право © 1993, 2011, Oracle и/или его филиалы. Все права защищены.

Использование исключительных ситуаций

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

class BadArgumentException extends RuntimeException public BadArgumentException () super () ;
>

public BadArgumentException ( String s ) super ( s ) ;
>
>

public class ExDemo1 static void processFile ( String fname ) throws IOException if ( fname == null || fname.length () == 0 ) throw new BadArgumentException () ;
>
FileInputStream fis = new FileInputStream ( fname ) ;
// . обработать файл .
fis.close () ;
>

public static void main ( String args []) try processFile ( «badfile» ) ;
> catch ( IOException e1 ) System.out.println ( «I/O error» ) ;
>

try processFile ( «» ) ;
> catch ( IOException e1 ) System.out.println ( «I/O error» ) ;
>
>
>

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

I/O error
Exception in thread «main» BadArgumentException
at ExDemo1.processFile ( ExDemo1.java: 18 )
at ExDemo1.main ( ExDemo1.java: 35 )

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

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

Определение собственных исключительных ситуаций в примере ExDemo1 не дает никаких преимуществ.

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

public class ExDemo2 static void processFile ( String fname ) throws IOException if ( fname == null || fname.length () == 0 ) throw new IllegalArgumentException ( «null or empty filename» ) ;
>
FileInputStream fis = new FileInputStream ( fname ) ;
// . обработать файл .
fis.close () ;
>

public static void main ( String args []) try processFile ( «badfile» ) ;
> catch ( IOException e1 ) System.out.println ( «I/O error» ) ;
>

try processFile ( «» ) ;
> catch ( IOException e1 ) System.out.println ( «I/O error» ) ;
>
>
>

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

I/O error
Exception in thread «main»
java.lang.IllegalArgumentException: null or empty filename
at ExDemo2.processFile ( ExDemo2.java: 7 )
at ExDemo2.main ( ExDemo2.java: 25 )

В этом примере есть еще третий момент, который необходимо отметить. Метод processFile вызывается дважды, первый раз с несуществующим именем файла, второй — с пустой строкой. В первом случае генерируется IOException, а во втором — IllegalArgumentException. Первая исключительная ситуация перехватывается, вторая нет.

Классы исключительных ситуаций

IOException является так называемой контролируемой исключительной ситуацией, в то время как IllegalArgumentException является исключительной ситуацией времени исполнения. Иерархия классов исключительных ситуаций в java.lang package выглядит следующим образом:

Throwable
Exception
RuntimeException
IllegalArgumentException
IOException
Error

Основное правило состоит в следующем: программа, вызывающая метод, который генерирует контролируемую исключительную ситуацию, должна обработать ее в операторе catch, либо передать ее далее. Другими словами, processFile вызывает конструктор FileInputStream, а затем метод FileInputStream.close. И конструктор и метод close генерируют контролируемую исключительную ситуацию IOException или ее подкласс FileNotFoundException. Таким образом, processFile должен перехватить эту исключительную ситуацию или определить, что он сам генерирует исключительную ситуацию. Поскольку он делает последнее, вызывающий его метод main должен перехватить исключительную ситуацию.

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

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

Третий тип исключительных ситуаций — подкласс Error, который зарезервирован, по соглашению, для виртуальной машин Java. OutOfMemoryError — это пример такого типа исключительной ситуации.

Сохранение объекта при генерировании исключительной ситуации

Еще один аспект использования исключительных ситуаций касается так называемой «неудачной элементарности», то есть, сохранение объекта в непротиворечивом состоянии при генерировании исключительной ситуации. Приведем пример:

class MyList <
private static final int MAXSIZE = 3 ;
private final int vec [] = new int [ MAXSIZE ] ;
private int ptr = 0 ;

public void addNum ( int i ) vec [ ptr++ ] = i;
/*
if (ptr == MAXSIZE) throw new ArrayIndexOutOfBoundsException(
«ptr == MAXSIZE»);
>
vec[ptr++] = i;
*/
>

public int getSize () return ptr;
>
>

public class ExDemo3 public static void main ( String args []) MyList list = new MyList () ;

try list.addNum ( 1 ) ;
list.addNum ( 2 ) ;
list.addNum ( 3 ) ;
list.addNum ( 4 ) ;
> catch ( ArrayIndexOutOfBoundsException e ) System.out.println ( e ) ;
>

System.out.println ( «size = » + list.getSize ()) ;
>
>

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

java.lang.ArrayIndexOutOfBoundsException
size = 4

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

Проблема в выражении «ptr++». Берется значение указателя списка, указатель инкрементируется и затем оригинальное значение используется для индексирования массива. Это индексирование вызывает исключительную ситуацию, а указатель уже установлен в новое, неправильное значение.

Решение этой проблемы приведено в закомментированном участке кода в классе MyList:

if ( ptr == MAXSIZE ) <
throw new ArrayIndexOutOfBoundsException ( «ptr == MAXSIZE» ) ;
>
vec [ ptr++ ] = i;

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

Избавление от «мусора»

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

Вот пример, демонстрирующий этот момент:

import java.io.*;
import java.util.*;

public class ExDemo4 static final int NUMFILES = 2048 ;
static final String FILENAME = «testfile» ;
static final String BADFILE = «» ;
static final List stream_list = new ArrayList () ;

// скопировать один файл в другой

public static void copyFile ( String infile, String outfile )
throws IOException

FileInputStream fis = new FileInputStream ( infile ) ;
stream_list.add ( fis ) ;
FileOutputStream fos = new FileOutputStream ( outfile ) ;

// если исключительная ситуация, дальше не выполнять

/*
FileInputStream fis = null;
FileOutputStream fos = null;
try fis = new FileInputStream(infile);
stream_list.add(fis);
fos = new FileOutputStream(outfile);
// . копировать файл .
>

// блок finally, выполняемый даже при
// возникновении исключительной ситуации

finally if (fis != null) fis.close();
>
if (fos != null) fos.close();
>
>
*/
>

public static void main ( String args []) throws IOException

new File ( FILENAME ) .createNewFile () ;

// периодически пытаться скопировать его в bad-файл

for ( int i = 1 ; i try copyFile ( FILENAME, BADFILE ) ;
> catch ( IOException e ) >
>

// отобразить количество успешных
// вызовов конструктора FileInputStream

System.out.println ( «open count = » + stream_list.size ()) ;

// попытаться открыть другой файл

FileInputStream fis = new FileInputStream ( FILENAME ) ;
>
>

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

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

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

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

open count = 1019
Exception in thread «main»
java.io.FileNotFoundException:
testfile ( Too many open files )
at java.io.FileInputStream.open ( Native Method )
at java.io.FileInputStream.
( FileInputStream.java: 64 )
at ExDemo4.main ( ExDemo4.java: 83 )

Решение этой проблемы дается в закомментированном коде в copyFile:

FileInputStream fis = null ;
FileOutputStream fos = null ;
try fis = new FileInputStream ( infile ) ;
stream_list.add ( fis ) ;
fos = new FileOutputStream ( outfile ) ;
// . копировать файл .
>

// блок finally, выполняемый даже при
// возникновении исключительной ситуации

finally if ( fis != null ) fis.close () ;
>
if ( fos != null ) fos.close () ;
>
>

Этот код вызывает закрытие потока входного файла и справляется с ситуацией, в которой выходной файл не может быть открыт. Если вы раскомментируете подходящий код (не забудьте закомментировать предыдущий код открытия/закрытия файла), вы получите следующий результат:

open count = 2048

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

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

Ссылки

Дополнительная информация об использовании исключительных ситуаций находится в разделах 40, 42, 45 и 46 книги «Эффективное руководство по языку программирования Java» Joshua Bloch (http://java.sun.com/docs/books/effective/).

Обратитесь также к разделу 12.3 «Финализация» книги «Язык программирования Java(tm), 3-е издание» Arnold, Gosling и Holmes

A может Вас также заинтересует что-нибудь из этого:
  1. Java сниппеты → Перехват необрабатываемых исключений
  2. Разное → Теория и практика Java: Динамическая компиляция и измерение производительности
  3. Java Standard Edition → Блокировки
  4. Java Standard Edition → Производительность операций ввода/вывода в Java
  5. Java сниппеты → Методы для работы с переменным количеством аргументов
  6. Разное → C# глазами Java программиста

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *