Правильное использование 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, и вы, вероятно, захотите поймать его в своей программе.