Caused by
日本語 | 例外の原因は |
英語 | this exception caused by |
ふりがな | こーずどばい |
フリガナ | コーズドバイ |
例外が発生した「本当の原因」。
ThrowableクラスやExceptionクラスは、コンストラクタで別の例外を格納することができる。この例外はgetCause()メソッドで取得でき、printStackTrace()メソッドで出力すると「Caused by:」に続けて出力される。
通常、この例外には「本当の原因」の例外を格納する。
例外は、throwsにより指定されたクラスしかメソッドから投げられることはない。そのため「実際に投げたい例外」と「throwsで投げられる例外」が異なる場合がある。その場合、throwsで指定された例外を投げ、その例外のインスタンスを作成する際にコンストラクタで「実際に投げたい例外」を渡すという方法を取ることができる。この方法により、デバッグ時に「本当の原因」を知ることができる。
ただし、「実際に投げたい例外」と「throwsで投げられる例外」が大きく異なる場合、この使用方法はお勧めしない。メソッドを呼び出す側は「throwsで投げられる例外」しか知ることができず、「実際に投げたい例外」に対して例外処理を行うのは困難なためである。そのような場合には「実際に投げたい例外」をthrowsに追加すべきである。もちろん、throwsの変更は呼び出し元メソッド全てに影響するため現実的に困難な場合も多い。
一般的な使用例としては、「throwsで投げられる例外」には「一般的なエラー処理」を意味する例外、たとえばServletExceptionクラスやJspExceptionクラスを使用する場合が多い。これらの例外は「単なる殻」とみなされ、「中に本当の原因が格納されている」ということが前提となっているからである。よってこういった例外のスタックトレースを見る場合には、まず「Caused by:」を探すことになる。
ThrowableクラスやExceptionクラスは、コンストラクタで別の例外を格納することができる。この例外はgetCause()メソッドで取得でき、printStackTrace()メソッドで出力すると「Caused by:」に続けて出力される。
通常、この例外には「本当の原因」の例外を格納する。
例外は、throwsにより指定されたクラスしかメソッドから投げられることはない。そのため「実際に投げたい例外」と「throwsで投げられる例外」が異なる場合がある。その場合、throwsで指定された例外を投げ、その例外のインスタンスを作成する際にコンストラクタで「実際に投げたい例外」を渡すという方法を取ることができる。この方法により、デバッグ時に「本当の原因」を知ることができる。
ただし、「実際に投げたい例外」と「throwsで投げられる例外」が大きく異なる場合、この使用方法はお勧めしない。メソッドを呼び出す側は「throwsで投げられる例外」しか知ることができず、「実際に投げたい例外」に対して例外処理を行うのは困難なためである。そのような場合には「実際に投げたい例外」をthrowsに追加すべきである。もちろん、throwsの変更は呼び出し元メソッド全てに影響するため現実的に困難な場合も多い。
一般的な使用例としては、「throwsで投げられる例外」には「一般的なエラー処理」を意味する例外、たとえばServletExceptionクラスやJspExceptionクラスを使用する場合が多い。これらの例外は「単なる殻」とみなされ、「中に本当の原因が格納されている」ということが前提となっているからである。よってこういった例外のスタックトレースを見る場合には、まず「Caused by:」を探すことになる。
参考サイト
// Sample.java
public class Sample
{
public static void main( String[] args )
{
try
{
try
{
// NullPointerExceptionを投げます。
throw new NullPointerException();
}
catch( NullPointerException e )
{
// 投げられたNullPointerExceptionを拾いました。
e.printStackTrace();
// java.lang.NullPointerException
// at Sample.main(Sample.java:11)
// さらに例外を投げます。
// その際、今受け取った例外を「原因」として
// 格納します。
throw new Exception( e );
}
}
catch( Exception e )
{
// 投げられたExceptionを拾いました。
e.printStackTrace();
// java.lang.Exception: java.lang.NullPointerException
// at Sample.main(Sample.java:23)
// Caused by: java.lang.NullPointerException
// at Sample.main(Sample.java:11)
// このように、元々の例外の情報も格納されています。
}
// 実際に良くあるパターン、throws指定に合わせて
// 例外を乗り換えてある例。
try
{
Sample sample = new Sample();
sample.throwsNewException();
}
catch( NewException e )
{
e.printStackTrace();
// NewException: java.lang.ClassNotFoundException
// at Sample.throwsNewException(Sample.java:71)
// at Sample.main(Sample.java:42)
// Caused by: java.lang.ClassNotFoundException
// at Sample.throwsNewException(Sample.java:61)
// ... 1 more
// このように、受け止めた例外が「殻」で、
// 本当の原因が中に入っていることは多々あります。
// 例外のスタックトレースを見るときには必ず
// Caused byがないかどうかチェックしましょう。
}
}
/**
* NewExceptionをthrows指定したメソッド。
*/
private void throwsNewException() throws NewException
{
// たとえばこの中でClassNotFoundExceptionが
// 投げられる可能性があり、それを拾う場合。
try
{
throw new ClassNotFoundException();
}
catch( ClassNotFoundException e )
{
e.printStackTrace();
// java.lang.ClassNotFoundException
// at Sample.throwsNewException(Sample.java:70)
// at Sample.main(Sample.java:42)
// ClassNotFoundExceptionを拾いました。
// が、ここで処理もできないので「また投げ」します。
// でもthrows指定で投げられるのはNewExceptionと
// 決まっているので、コンストラクタで
// 「原因」として渡します。
throw new NewException( e );
// ただし!
// たとえば、拾った例外がNullPointerExceptionで、
// throwsでの指定がClassNotFoundExceptionだった場合に、
// 同じように詰め込んで投げるのはやめましょう。
// こういう例が許されるのは、throwsで指定されたクラスが
// 総称的な意味を持つクラス(たとえばServletException)の
// 場合だけです。
}
}
}
/**
* 新しい自分専用例外クラス。
*/
class NewException extends Exception
{
/**
* Exception( Throwable )のオーバーライド(?)コンストラクタ。
*/
public NewException( Throwable e )
{
super( e );
}
}
public class Sample
{
public static void main( String[] args )
{
try
{
try
{
// NullPointerExceptionを投げます。
throw new NullPointerException();
}
catch( NullPointerException e )
{
// 投げられたNullPointerExceptionを拾いました。
e.printStackTrace();
// java.lang.NullPointerException
// at Sample.main(Sample.java:11)
// さらに例外を投げます。
// その際、今受け取った例外を「原因」として
// 格納します。
throw new Exception( e );
}
}
catch( Exception e )
{
// 投げられたExceptionを拾いました。
e.printStackTrace();
// java.lang.Exception: java.lang.NullPointerException
// at Sample.main(Sample.java:23)
// Caused by: java.lang.NullPointerException
// at Sample.main(Sample.java:11)
// このように、元々の例外の情報も格納されています。
}
// 実際に良くあるパターン、throws指定に合わせて
// 例外を乗り換えてある例。
try
{
Sample sample = new Sample();
sample.throwsNewException();
}
catch( NewException e )
{
e.printStackTrace();
// NewException: java.lang.ClassNotFoundException
// at Sample.throwsNewException(Sample.java:71)
// at Sample.main(Sample.java:42)
// Caused by: java.lang.ClassNotFoundException
// at Sample.throwsNewException(Sample.java:61)
// ... 1 more
// このように、受け止めた例外が「殻」で、
// 本当の原因が中に入っていることは多々あります。
// 例外のスタックトレースを見るときには必ず
// Caused byがないかどうかチェックしましょう。
}
}
/**
* NewExceptionをthrows指定したメソッド。
*/
private void throwsNewException() throws NewException
{
// たとえばこの中でClassNotFoundExceptionが
// 投げられる可能性があり、それを拾う場合。
try
{
throw new ClassNotFoundException();
}
catch( ClassNotFoundException e )
{
e.printStackTrace();
// java.lang.ClassNotFoundException
// at Sample.throwsNewException(Sample.java:70)
// at Sample.main(Sample.java:42)
// ClassNotFoundExceptionを拾いました。
// が、ここで処理もできないので「また投げ」します。
// でもthrows指定で投げられるのはNewExceptionと
// 決まっているので、コンストラクタで
// 「原因」として渡します。
throw new NewException( e );
// ただし!
// たとえば、拾った例外がNullPointerExceptionで、
// throwsでの指定がClassNotFoundExceptionだった場合に、
// 同じように詰め込んで投げるのはやめましょう。
// こういう例が許されるのは、throwsで指定されたクラスが
// 総称的な意味を持つクラス(たとえばServletException)の
// 場合だけです。
}
}
}
/**
* 新しい自分専用例外クラス。
*/
class NewException extends Exception
{
/**
* Exception( Throwable )のオーバーライド(?)コンストラクタ。
*/
public NewException( Throwable e )
{
super( e );
}
}
// Sample.java public class Sample { public static void main( String[] args ) { try { try { // NullPointerExceptionを投げます。 throw new NullPointerException(); } catch( NullPointerException e ) { // 投げられたNullPointerExceptionを拾いました。 e.printStackTrace(); // java.lang.NullPointerException // at Sample.main(Sample.java:11) // さらに例外を投げます。 // その際、今受け取った例外を「原因」として // 格納します。 throw new Exception( e ); } } catch( Exception e ) { // 投げられたExceptionを拾いました。 e.printStackTrace(); // java.lang.Exception: java.lang.NullPointerException // at Sample.main(Sample.java:23) // Caused by: java.lang.NullPointerException // at Sample.main(Sample.java:11) // このように、元々の例外の情報も格納されています。 } // 実際に良くあるパターン、throws指定に合わせて // 例外を乗り換えてある例。 try { Sample sample = new Sample(); sample.throwsNewException(); } catch( NewException e ) { e.printStackTrace(); // NewException: java.lang.ClassNotFoundException // at Sample.throwsNewException(Sample.java:71) // at Sample.main(Sample.java:42) // Caused by: java.lang.ClassNotFoundException // at Sample.throwsNewException(Sample.java:61) // ... 1 more // このように、受け止めた例外が「殻」で、 // 本当の原因が中に入っていることは多々あります。 // 例外のスタックトレースを見るときには必ず // Caused byがないかどうかチェックしましょう。 } } /** * NewExceptionをthrows指定したメソッド。 */ private void throwsNewException() throws NewException { // たとえばこの中でClassNotFoundExceptionが // 投げられる可能性があり、それを拾う場合。 try { throw new ClassNotFoundException(); } catch( ClassNotFoundException e ) { e.printStackTrace(); // java.lang.ClassNotFoundException // at Sample.throwsNewException(Sample.java:70) // at Sample.main(Sample.java:42) // ClassNotFoundExceptionを拾いました。 // が、ここで処理もできないので「また投げ」します。 // でもthrows指定で投げられるのはNewExceptionと // 決まっているので、コンストラクタで // 「原因」として渡します。 throw new NewException( e ); // ただし! // たとえば、拾った例外がNullPointerExceptionで、 // throwsでの指定がClassNotFoundExceptionだった場合に、 // 同じように詰め込んで投げるのはやめましょう。 // こういう例が許されるのは、throwsで指定されたクラスが // 総称的な意味を持つクラス(たとえばServletException)の // 場合だけです。 } } } /** * 新しい自分専用例外クラス。 */ class NewException extends Exception { /** * Exception( Throwable )のオーバーライド(?)コンストラクタ。 */ public NewException( Throwable e ) { super( e ); } }