Правильное использование IllegalArgumentException
оригинальный вопрос здесь
Я читаю в файле UTF-8 и анализирую содержимое этого файла. Если в файле есть ошибка, нет смысла продолжать, и выполнение должно прекратиться. Мне предложили бросить IllegalArgumentException если есть проблемы с содержимым, но документ API говорит:
брошенный, чтобы указать, что метод был принят незаконный или неуместный аргумент.
В моем коде, аргумент был бы файл (или фактически путь), который я передаю, правильно ли бросить IllegalArgumentException в случае если что-то пойдет не так во время парсинга? Если нет, то какое исключение я должен бросить?
private char[][] readMazeFromFile(Path mazeFile) throws IOException {
if (!Files.isRegularFile(mazeFile) || !Files.isReadable(mazeFile)) {
throw new IllegalArgumentException("Cannot locate readable file " + mazeFile);
}
List<String> stringList = Files.readAllLines(mazeFile, StandardCharsets.UTF_8);
char[][] charMaze = new char[stringList.size()][];
for (int i = 0; i < stringList.size(); i++) {
String line = stringList.get(i);
if (line.length() != charMaze.length)
throw new IllegalArgumentException(String.format("Expect the maze to be square, but line %d is not %d characters long", line.length(), charMaze.length));
if (line.contains("B")) {
startX = i;
startY = line.indexOf("B");
}
if (line.contains("F")) {
endX = i;
endY = line.indexOf("F");
}
charMaze[i] = line.toCharArray();
}
if (startX == -1 || startY == -1)
throw new IllegalArgumentException("Could not find starting point (B), aborting.");
if (endX == -1 || endY == -1)
throw new IllegalArgumentException("Could not find ending point (F), aborting.");
return charMaze;
}
3 ответов
Я думаю, что первое использование правильно:
if (!Files.isRegularFile(mazeFile) || !Files.isReadable(mazeFile)) {
throw new IllegalArgumentException("Cannot locate readable file "+mazeFile);
}
поскольку (как указано в документации) в качестве аргумента был предоставлен недопустимый файл, это должно вызвать IllegalArgumentException.
Как только вы узнаете, что у вас есть фактический файл, который соответствует этим требованиям, я лично не думаю, что это хорошее исключение. Это заставит других разработчиков усомниться в типе аргумента, который был задан в отличие от содержимого файла. Думаю, у тебя есть варианты. являются:
держите его как есть, только с очень конкретные сообщения об ошибке, объясняющее почему это был неверный аргумент.
используйте другое, потенциально более применимое исключение java, такое как
java.text.ParseException, так как это разбор файла, который вызывает ошибку.создайте пользовательский класс исключений, который более подробно описывает проблему с файлом, например a
MazeParseException(согласно комментарии) илиFileFormatException.
Я ожидаю, что второй или третий вариант будет более выгодным, если вы ожидаете, что несколько других разработчиков выполнят вашу функцию.
исключения в основном не что иное, как имена, мой лучший совет здесь было бы сделать свой собственный.
Основная причина в том, что IllegalArgumentExceptionС неотмеченные исключения потому что они расширяют java.lang.RuntimeException. Они просто вызовут проблемы, если вы используете их в таком контексте.
(источник)
измените сигнатуру метода на
private char[][] readMazeFromFile(Path mazeFile) throws IOException, MazeParseException {...}
и throw new IllegalArgumentException С throw new MazeParseException
(за исключением первого использования в соответствии с ответом @Joel)
в MazeParseException.файл java:
package yourPackage.here;
import java.lang.Exception;
public class MazeParseException {
public MazeParseException() {
super();
}
public MazeParseException(String reason) {
super(reason);
}
}
преимущества использования вашего собственного исключения в том, что вы можете пометить дополнительные данные вместе с исключением, относящимся к вашей ситуации, например, вы можете добавить:
private int errorLineNum = null;
public MazeParseException(String reason, int lineNum) {
this(reason);
this.errorLineNum = lineNum;
}
public int getMalformedLine() {
return this.errorLineNum;
}
// And then update the toString() method to incorperate the errorLineNum
@Override
public String toString() {
StringBuilder sb = new StringBuilder(super.toString());
if(errorLineNum != null) {
sb.append("@ line #");
sb.append(this.errorLineNum);
}
return sb.toString();
}
поскольку JSON или XML-библиотека отправляют свое собственное исполнение, если файл не соответствует тому, что они ищут (файл JSON или XML), я думаю, вы должны сделать то же самое, если не соответствует тому, что вы ищете( файл UTF-8 ).
IllegalArgumentException должен использоваться для внутренней проблемы в коде и не должен быть брошен, когда ваш код был отлажен. Также вы не должны поймать IllegalArgumentException, и вы, вероятно, захотите поймать его в своей программе.