web-dev-qa-db-ja.com

コンストラクターはJavaで例外をスローできますか?

コンストラクターは例外をスローできますか?

217
Mahmoud Hossam

はい、コンストラクターは例外をスローできます。通常、これは、新しいオブジェクトがガベージコレクションにすぐに適格であることを意味します(もちろん、しばらくは収集されない場合があります)。 「半分構築された」オブジェクトは、コンストラクターの前の方で(たとえば、静的フィールドを割り当てるか、コレクションに追加することで)自分自身を可視化した場合でも、動き続ける可能性があります。

コンストラクターで例外をスローする際に注意する必要があること:呼び出し元は(通常)新しいオブジェクトを使用する方法がないため、コンストラクターはアンマネージリソース(ファイルハンドルなど)を取得して例外をスローしないように注意する必要がありますそれらを解放することなく。たとえば、コンストラクターがFileInputStreamおよびFileOutputStreamを開こうとし、最初のものが成功したが2番目のものが失敗した場合、最初のストリームを閉じてみてください。もちろん、例外をスローするサブクラスコンストラクターの場合、これは難しくなります。もちろん、すべてが少しトリッキーになります。それほど頻繁に問題になることはありませんが、検討する価値があります。

347
Jon Skeet

はい、例外をスローできます。その場合、それらは部分的にのみ初期化され、最終的でない場合は攻撃を受けます。

以下は Secure Coding Guidelines 2. からのものです。

非ファイナルクラスの部分的に初期化されたインスタンスには、ファイナライザー攻撃を介してアクセスできます。攻撃者は、サブクラスの保護されたfinalizeメソッドをオーバーライドし、そのサブクラスの新しいインスタンスを作成しようとします。この試みは失敗します(上記の例では、ClassLoaderのコンストラクターのSecurityManagerチェックはセキュリティ例外をスローします)が、攻撃者は例外を単に無視し、仮想マシンが部分的に初期化されたオブジェクトでファイナライズを実行するのを待ちます。それが発生すると、悪意のあるファイナライズメソッドの実装が呼び出され、攻撃者はこれにアクセスでき、ファイナライズされるオブジェクトへの参照が得られます。オブジェクトは部分的にのみ初期化されますが、攻撃者は引き続きオブジェクトのメソッドを呼び出すことができます(これにより、SecurityManagerチェックを回避します)。

78
Billy Bob Bain

絶対に。

コンストラクターが有効な入力を受け取らない場合、または有効な方法でオブジェクトを構築できない場合は、例外をスローして呼び出し元に警告する以外のオプションはありません。

32
Yuval

はい、例外をスローできます。また、以下の例に示すように、コンストラクターのシグネチャでも例外を宣言できます。

public class ConstructorTest
{
    public ConstructorTest() throws InterruptedException
    {
        System.out.println("Preparing object....");
        Thread.sleep(1000);
        System.out.println("Object ready");
    }

    public static void main(String ... args)
    {
        try
        {
            ConstructorTest test = new ConstructorTest();
        }
        catch (InterruptedException e)
        {
            System.out.println("Got interrupted...");
        }
    }
}
14
V_Singh

はい、コンストラクターは例外をスローできます。

ただし、どの例外を選択すべきかについては、非常に賢明です-チェック済み例外またはチェックなし。未チェックの例外は、基本的にRuntimeExceptionのサブクラスです。

ほとんどすべての場合(このケースの例外を思い付くことができませんでした)、チェック済み例外をスローする必要があります。理由は、未チェックの例外(NullPointerExceptionなど)は通常、プログラミングエラー(入力を十分に検証していないなど)が原因であるためです。

チェック例外が提供する利点は、プログラマがインスタンス化コードで例外をキャッチすることを余儀なくされ、それによりオブジェクトインスタンスの作成に失敗する可能性があることを認識することです。もちろん、例外を飲み込むという貧弱なプログラミング手法をキャッチできるのはコードレビューだけです。

11
Vineet Reynolds

はい。

コンストラクタは特別なメソッドにすぎず、他のメソッドと同様に例外をスローできます。

7
Isaac