2017-08-20 16 views
0

状況に応じて - メインメソッドでは、オブジェクトをチェックする子メソッドが呼び出され、この子メソッドで例外がスローされます(オブジェクトの1つリストのNULLに)。しかし、メインメソッドのコードはまだ実行され続けています! コード例:この点で例外がスローされ、さらにコードが実行される

@Transactional 
public boolean addCompany(List<Company> companies, List<Address> addresses) throws Exception{ 
    checkAddress(addresses); 
    try{ 
     for(int i = 0; i < companies.size(); i++){ 
      if(findCompany(companies.get(i).getId()) == null && !isExistsCompany(companies.get(i))){ 
       companies.get(i).setAddress(addresses.get(i)); 
       this.em.persist(companies.get(i)); 
      } 
     } 
    }catch(Exception e){ 
     return false; 
    } 
    return true; 
} 

public void checkAddress(List<Address> addresses) throws Exception{ 
    try{ 
     if(addresses == null) 
      throw new Exception(Thread.currentThread().getStackTrace()[2].getClassName() + "." + Thread.currentThread().getStackTrace()[2].getMethodName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName() + ": Invalid parameter: list is null"); 
     for(Address a : addresses) 
      if(a == null) 
       throw new Exception(Thread.currentThread().getStackTrace()[2].getClassName() + "." + Thread.currentThread().getStackTrace()[2].getMethodName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName() + ": Invalid list item: object is null"); 
    }catch(Exception e){ 
     e.printStackTrace(); 
    } 
} 

、いくつかの質問が生じた: を - コードが停止しない理由は? - オプションとして、checkAddressメソッドの型をvoidからbooleanに変更し、true/falseを処理するmainメソッドで状況を脱出する必要がありますか? - フロントエンドでこのようなエラーを正しく処理する方法 - テキストをフロントエンドに送信するか、コード500を処理するだけですか?その場合は、バックエンドで例外を生成する理由を開発プロセスで助けてください。それをうまく処理するには? アドバイスをお願いします。 ありがとうございます。

+0

私はあなたがこのコード例である知っているが、私は、全体 'getStackTraceメソッド()[n]は'事は悪い考えであることを指摘する必要性を感じます可読性上の理由とパフォーマンス上の理由だけでなく、JVMがスタックフレームを削除できるためです。クラス名とメソッド名を[特定のLoggerメソッドが行う](https://docs.oracle.com/javase/8/docs/api/java/util/logging/Logger)のようにString引数として渡す方がずっと良い方法です。 html#entering-java.lang.String-java.lang.String-)。 – VGR

+0

getStackTrace()がなければ、現在のクラスとメソッドの名前をLoggerに渡す方法は他にありますか? – Denis

+0

checkAddressはその情報を取得しようとすべきではありません。呼び出し元は代わりにそれらをパラメータとして渡す必要があります。私がリンクしているLoggerメソッドのように。 – VGR

答えて

0

はこれを試してみてください:スレッドに関するすべてのものです

public void checkAddress(List<Address> addresses) throws Exception{ 
     if(addresses == null) 
      throw new Exception(Thread.currentThread().getStackTrace()[2].getClassName() + "." + Thread.currentThread().getStackTrace()[2].getMethodName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName() + ": Invalid parameter: list is null"); 
     for(Address a : addresses) 
      if(a == null) 
       throw new Exception(Thread.currentThread().getStackTrace()[2].getClassName() + "." + Thread.currentThread().getStackTrace()[2].getMethodName() + "." + Thread.currentThread().getStackTrace()[1].getMethodName() + ": Invalid list item: object is null"); 
    } 

} 

何?クレイジーコード。

誰もが最初にNullインスタンスをリストに追加することを許可しないでください。

私はそれをこのように書くかもしれません:

public void checkAddresses(List<Address> addresses) { 
    if (addresses == null) throw new IllegalArgumentException("Address List cannot be null"); 
    for (Address a : addresses) { 
     if (a == null) throw new IllegalArgumentException("Address cannot be null"); 
    } 
} 
+0

getStackTrace()を使用して、エラーが発生したパッケージ/クラス/メソッドを自分自身に示します。同じメソッドがコード内で何回も呼び出され、エラーが発生した場合は、このエラーが発生した場所をすばやく見つける必要があります。このようなスティグを印刷すると、エラーのあるメソッドへの絶対パスが得られます。 – Denis

+0

あなたはすべてのノイズを必要としません。これはチェックされていない例外です。呼び出し元に例外をキャッチさせて、何が起こったのかを伝えるようアドバイスします。アドレスメソッドは、そのようにコンテキストを提供するべきではありません。それは私がそれを書いたときにそれがどのように呼び出されたのかを知る必要はない。 – duffymo

+0

ありがとう!さらにもう1つの質問 - 例外がいつ働いたのですか?フロントエンドを渡すようにアドバイスしますか?デフォルトでは、エラーコード500が送信されます。例外テキストを渡す価値がありますか、それとも別のトーンですか、エラー500を処理するだけですか? – Denis

1
e.printStackTrace(); 

この行はあなたのコードが継続ではなく、失敗する原因、例外を抑制することができます。それは例外がスローされているように見えるかもしれないスタックトレースを出力しますが、それ以上の行は得られません。

ほとんどの場合、printStackTrace()を使用したくない場合は、意図した例外を適切に処理するか、例外をメソッドの呼び出し元に伝播させるだけです。

+0

スタックトレースを印刷しても例外は処理されません。メソッドが例外をスローするようにしたいのであれば、それをtry/catchブロックでラップするのはなぜですか? – duffymo

+0

@duffymo私はあなたに同意します。そのため、私は 'printStackTrace()'の使用をお勧めしません。あなたが何を反対しているのか分かりません。 '.printStackTrace()'は、ユーザーがtry-catchブロックをキャッチのボディとして追加しようとすると、IDEによって自動的に追加されることがよくあります。 – dimo414

1

checkAddress()メソッド内からtry .. catchブロックを削除する必要があります。こうすると、checkAddress()の内部からスローされた例外がすべてその呼び出し元に伝播します。

addCompany()メソッドでは、checkAddress()メソッドをtrycatchの中に呼び出して例外を処理します。

checkAddress()が例外をスローすると、コード実行がcatchブロックにジャンプします。

2

あなたはJavaランタイムがそれを扱う考慮Exceptionを再スローしていないときは、Exception(複数可)キャッチされています。プログラムの実行が停止することを期待した場合は、Exceptionが発信者に伝播する必要があります。例えば、

} catch(Exception e) { 
    e.printStackTrace(); 
    throw e; // <-- re-throw the Exception 
} 

またはのようなものにcheckAddress変更

} catch(Exception e) { 
    e.printStackTrace(); 
} 

に単にそれからExceptionを自動的に呼び出し側にスローされ、完全にtrycatchを削除します。また、Java 8以降ではStreamを使用できます。同様に、

public void checkAddress(List<Address> addresses) throws Exception { 
    if (addresses == null) { 
     StackTraceElement[] ste = Thread.currentThread().getStackTrace(); 
     throw new Exception(ste[2].getClassName() + "." 
       + ste[2].getMethodName() + "." + ste[1].getMethodName() 
       + ": Invalid parameter: list is null"); 
    } 
    if (addresses.stream().anyMatch(a -> a == null)) { 
     StackTraceElement[] ste = Thread.currentThread().getStackTrace(); 
     throw new Exception(ste[2].getClassName() + "." 
       + ste[2].getMethodName() + "." + ste[1].getMethodName() 
       + ": Invalid list item: object is null"); 
    } 
} 
+0

あなたは 'addresses.stream()。anyMatch(Objects :: isNull)'を行うことさえできます。 – VGR

関連する問題