6

domanda originale è hereutilizzo corretto del IllegalArgumentException

Sto leggendo in un file UTF-8 e l'analisi del contenuto di quel file. Se c'è un errore nel file non ha senso continuare e l'esecuzione dovrebbe fermarsi. Mi è stato suggerito di lanciare IllegalArgumentException se ci sono problemi con i contenuti, ma la documentazione delle API dice:

gettato per indicare che un metodo è stato passato un argomento illegale o inappropriato.

Nel mio codice, l'argomento sarebbe il file (o in realtà il percorso) che mi passa, è corretto gettare IllegalArgumentException in caso qualcosa vada storto durante l'analisi? In caso contrario, quale tipo di eccezione dovrei lanciare?

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

No in questi casi non si dovrebbe lanciare un IllegalArgumentException. Forse un'eccezione personalizzata come MazeParseException (come SAXException quando si utilizza DocumentBuilder.parse()). Utilizzare IllegalArgumentExceptions quando non si desidera accettare i valori nulli ma è stato fornito un valore nullo o se è richiesta una cartella ma è stato fornito un file, ecc. – Icewind

+2

Direi che questa domanda è tendenzialmente basata principalmente sull'opinione. Personalmente non mi preoccuperei di creare una nuova classe di eccezioni in questo caso, mi limiterei a lanciare un 'RuntimeException' con un messaggio di errore appropriato. – JonK

+1

IllegalArgumentException va perfettamente bene qui. L'oggetto Path non soddisfa i requisiti del metodo. –

risposta

5

Penso che il primo utilizzo è corretto:

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

Dal momento che (come gli stati di documentazione) un file non valido è stato fornito come argomento, questo dovrebbe lanciare un IllegalArgumentException. Una volta che sai di avere un file vero e proprio che soddisfa quei requisiti, personalmente non penso che sia una buona eccezione per il lancio. Ciò indurrà altri sviluppatori a mettere in discussione il tipo di argomento che è stato fornito rispetto al contenuto del file. Credo che le opzioni sono:

  • non apportare modifiche, solo con messaggi di errore molto specifiche spiegando perché questo era un argomento non valido.

  • Utilizzare qualche altra eccezione java potenzialmente più applicabile come java.text.ParseException, poiché è l'analisi del file che causa l'errore.

  • Creare una classe di eccezioni personalizzata che descriva in modo più sufficiente il problema con il file, ad es. a MazeParseException (per i commenti) o a FileFormatException.

Mi aspetto che la seconda o terza opzione sia più utile se si anticipano molti altri sviluppatori che eseguono la propria funzione.

0

Come JSON o XML libreria di inviare i propri execption se il file non corrisponde a ciò che stanno cercando (un file JSON o XML uno), penso che si dovrebbe fare lo stesso, se non corrisponde quello che stai cercando (un file UTF-8).

IllegalArgumentException deve essere utilizzato per problemi interni nel codice e non deve essere lanciato quando il codice è stato eseguito correttamente. Inoltre non dovresti prendere un IllegalArgumentException e probabilmente vorrai prenderlo nel tuo programma.

1

Le eccezioni sono principalmente nient'altro che nomi, il mio miglior consiglio qui sarebbe quello di crearne uno proprio. Il motivo principale è che IllegalArgumentException s sono eccezioni non selezionate perché estendono java.lang.RuntimeException. Avrebbero solo problemi se li avessi usati in un contesto come questo. (Source)

cambiare il metodo di firma

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

E tutto throw new IllegalArgumentException con throw new MazeParseException (fatta eccezione per il primo utilizzo come da @ risposta di Joel)

Il file MazeParseException.java:

package yourPackage.here; 

import java.lang.Exception; 

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

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

I vantaggi qui di usare la propria e xception è che puoi taggare dati extra insieme all'eccezione relativa alla tua situazione, ad esempio puoi aggiungere:

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

} 
Problemi correlati