6

原题正确的用法是here的抛出: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

否在这种情况下,您不应该抛出IllegalArgumentException。也许像MazeParseException这样的自定义异常(如使用DocumentBuilder.parse()时的SAXException)。使用IllegalArgumentExceptions当你不想接受空值,但给出空值,或者如果你需要一个文件夹,但给出了一个文件等。 – Icewind

+2

我会说这个问题是主要基于意见的基础上接近。我个人不会在这种情况下创建一个新的异常类,我只是抛出一个'RuntimeException'和一个适当的错误消息。 – JonK

+1

IllegalArgumentException在这里完全没问题。 Path对象不符合该方法的要求。 –

回答

5

我认为第一种用法是正确的:

if (!Files.isRegularFile(mazeFile) || !Files.isReadable(mazeFile)) { 
    throw new IllegalArgumentException("Cannot locate readable file "+mazeFile); 
} 

由于(如文档状态)无效的文件被作为参数提供,这应该抛出IllegalArgumentException。 一旦你知道你有一个符合这些要求的实际文件,我个人认为这不是一个很好的例外。这会导致其他开发人员质疑与文件内容相反的参数类型。我猜你的选择是:

  • 保持原样,只是非常特定错误消息解释 为什么这是一个无效的参数。

  • 使用一些其他可能更适用的Java异常,例如java.text.ParseException,因为它是导致错误的文件解析。

  • 创建一个自定义异常类,以更充分地描述文件的问题,例如,一个MazeParseException(根据评论)或一个FileFormatException

如果您预计其他几个开发人员正在执行您的功能,我希望第二个或第三个选项更有用。

0

JSON或XML库派出自己的execption如果文件不匹配,他们正在寻找(一个JSON文件或XML之一),我认为你应该做相同的,如果不匹配你在找什么(一个UTF-8文件)。

IllegalArgumentException应该用于代码中的内部问题,并且在代码调试时不应抛出。此外,您不应该捕获IllegalArgumentException,并且您可能希望在程序中捕获它。

1

例外主要是什么,但名称,我最好的建议是在这里做你自己的。 主要原因是IllegalArgumentException s是未检查的例外因为它们延伸java.lang.RuntimeException。如果你在这样的环境中使用它们,它们会造成问题。 (Source)

更改方法签名

private char[][] readMazeFromFile(Path mazeFile) throws IOException, MazeParseException {...} 

而且所有throw new IllegalArgumentExceptionthrow new MazeParseException (除第一次使用按@乔尔的回答)

的MazeParseException.java文件:

package yourPackage.here; 

import java.lang.Exception; 

public class MazeParseException { 
    public MazeParseException() { 
     super(); 
    } 

    public MazeParseException(String reason) { 
     super(reason); 
    } 
} 

使用您自己的e xception是,您可以标记额外的数据以及与您的情况有关的例外情况,例如,您可以添加:

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(); 

} 
相关问题