2016-05-08 11 views
0

私は例外について多くのことを読んだことがありますが、私は一緒にすべてを組み立てるのに苦労しています...私はファイルを読むためのユーティリティメソッドを書こうとしています(これは練習用ですので興味はありません)ライブラリを使用して:エラーを正確に特定する最も良い方法は何ですか?

public static List<String> readFile(String file) 
     throws NoSuchFileException, 
       AccessDeniedException, 
       SomeException1, 
       SomeException2, 
       IOException { 
    Path p = Paths.get(file); 
    if (!Files.exists(p)) { 
     throw new NoSuchFileException(file); 
    } else if (!Files.isRegularFile(p)) { 
     throw new SomeException1(file); 
    } else if (!Files.isReadable(p)) { 
     throw new AccessDeniedException(file); 
    } else if (Files.size(p) == 0) { 
     throw new SomeException2(file); 
    } 
    return Files.readAllLines(p); 
} 


public static void main(String[] args) { 
    try { 
     if (args.length != 2) { 
      System.out.println("The proper use is: java MyProgram file1.txt file2.txt"); 
      return; 
     } 

     List<List<String>> files = new ArrayList<>(); 
     for (int i = 0; i < args.length; i++) { 
      try { 
       files.add(Utilities.readFile(args[i])); 
      } catch (NoSuchFileException e) { 
       System.out.printf("File %s does not exist%n", e.getMessage()); 
       System.exit(-1); 
      } catch (SomeException1 e) { 
       System.out.printf("File %s is not a regular file%n", e.getMessage()); 
       throw e; 
      } catch (AccessDeniedException e) { 
       System.out.printf(
        "Access rights are insufficient to read file %s%n", e.getMessage() 
       ); 
       throw new AccessDeniedException(e); 
      } catch (SomeException2 e) { 
       System.out.printf("File %s is empty%n", e.getMessage()); 
       throw new SomeOtherException(e); 
      } 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

私は後でそれらをキャッチし、ユーザーに関連するエラーメッセージを書き込みますが、これは悪い見ることができますので、正確な例外をスローしたい...と、これを行うには良い方法はありますか?

私が見るいくつかの問題がここにありますが私の考えです:

  1. 私は、これは例外的なケースである、フロー制御ではないかなり確信しているので、私は例外を使用する必要があります。
  2. 一般的な例外をスローすることはできません。エラーの原因を特定できません。
  3. 一方、これはあまりにも多くの例外のように、メソッドのシグネチャを汚染するように感じます。さらに、チェックされていない例外を使用することはできません。プログラマのエラーではなく、処理できます。
  4. そして、私の使用事例で十分正確な標準例外を見つけることはできません。あなたの例外は、すべての由来している場合は
  5. しかし、私は、これは例外のカスタムタイプを作成するための適切な時期があるのか​​はわからないか、これが問題に対処するために間違った方法であれば...
+0

elseは不要です。最初のifがtrueの場合、例外がスローされ、メソッドの残りの部分には到達しません。 – flup

+0

ifsにする利点はありますか? – kevinlelo

+0

彼らは多少読みやすくなりますが、それは味の問題です。プラスあなたはそれらをオンライナーにすることができます。 – flup

答えて

2

あなたはそれぞれの例外に添付されたメッセージを使用して、すべてのケースごとに異なる例外を作成したくない場合は

public static List<String> readFile(String file) 
     throws IOException { 
    // ... 
} 

:共通のベース例外は、たとえばIOExceptionのために、ベース例外のthrows宣言を追加するのに十分です:

public static List<String> readFile(String file) 
     throws IOException { 
    Path p = Paths.get(file); 
    if (!Files.exists(p)) { 
     throw new IOException("No such file: " + file); 
    } else if (!Files.isRegularFile(p)) { 
     throw new IOException("No regular file: " + file); 
    } else if (!Files.isReadable(p)) { 
     throw new IOException("Access denied: " + file); 
    } else if (Files.size(p) == 0) { 
     throw new IOException("Empty file: " + file); 
    } 
    return Files.readAllLines(p); 
} 

エラー処理のために行う必要があるのは、エラーメッセージを出力することだけです。これは良いオプションです。

+0

共通の例外の良い点は、私はそれを知らなかった!しかし、IOExceptionはかなり一般的な型なので、私はここでキャッチしたくない、または表示するには良いメッセージがない他の例外をキャッチするかもしれません...それは私が一般的な例外で持っていた問題です。 – kevinlelo

0

例外は、オブジェクト階層の一部である場合があります。例外を詳細に扱うことができます。または、抽象度の高い任意のレベルで処理できます。たとえば、FileNotFoundExceptionCharacterEncodingExceptionの両方がIOExceptionに拡張されます。あなたは抽象IOExceptionレベルでそれらをキャッチするために選択するか、次のように個別に対処できます。

catch(FileNotFouncException e){ 
    // handle it specifically 
} 
catch(CharacterEncodingException e){ 
    // handle it specifically 
} 
catch(IOException e){ 
    // all others handle the same way 
    // (Superclass must be handled after subclasses) 
} 

ができませそれらを処理したいという理由だけで、便利な共通の基底クラスを持っていないにもグループの例外同じように、次のように:

+0

IOExceptionを除いて、これらの例外をすべて特に処理するのはいいですか?私はそれぞれのエラーが適切な対応に値するように感じますが、私が詳細に行き過ぎるかどうか疑問に思っていました... – kevinlelo

+0

これは、必要に応じてさまざまなレベルの抽象化をどのように処理できるかを示す単なる例でした。それぞれの例外タイプで何をするか自分自身に尋ねます。単に 'getMessage()'を呼び出して、それぞれに対して同じ方法で応答しますか?できるだけ抽象的な例外タイプを使用してください。それぞれ違う反応をしますか?特定のタイプを使用してください。あなたは混合物をしますか?最初に特定の型を処理し、抽象型をキャッチオールとして使用して正常に失敗するようにします。 –

関連する問題