2013-04-20 14 views
5

私はクラスのコンストラクタを2つ持っています.1つはオブジェクトを受け取り、もう1つはthisキーワードを使用します。実装の関数は、Fileをパラメータとし、Stringの関数はthisを呼び出します。今私はStringを取るコンストラクタで例外をチェックしたいが、私はエラーを得る、そのthisは、最初の行にする必要があります。エラーを確認するには、thisに電話してください。ここでコンストラクタが例外を処理し、このキーワードを使用しています。Java

は私のコードです:

public Test (String filename) { 
    if (filename == null) 
     throw new NullPointerException("The String you entered is null."); 
    if (filename.isEmpty()) 
     throw new IllegalArgumentException("The String you entered is empty."); 

    this(new File(filename)); // error 
} 

public Test (File f) { 
    /* implementation here */ 
} 

これは、正確なエラーです:Constructor call must be the first statement in a constructor

+0

どのようなエラーが表示されますか? – Thomas

+0

投稿されたコードはあなたが説明したものとちょうど反対です! – NINCOMPOOP

答えて

2

は残念ながら、これはJavaで自分の任意の制限のおかげでは不可能です。あなたには2つの主要な可能性があります。

もっと慣れ親しんだJavaのテクニックは、すべてをファクトリ関数でラップして例外をキャッチすることです。ファクトリ関数は、オブジェクトを多態的に作成し、実際に作成されたオブジェクトの詳細を隠すことができるので便利です。

もう1つのオプションは、そのような制限が存在しないバイトコードにコンストラクタを書き込むことです。残念なことに、バイトコードの読み込みと保守は容易ではないため、主にJavaアプリケーションでバイトコードの量を最小限に抑えたいと思うでしょう。 AspectJのようなJava以外の言語でもこれを行うことができます。

編集:実際に例外をキャッチしようとしていない場合、3番目の可能性があります。スーパーコンストラクター呼び出しの前に任意のコードを挿入することができます。これは、チェックを実行する別の関数を作成し、それをスーパーコンストラクター呼び出しの仮引数として渡します。引数が最初に評価されるので、コードが最初に実行されますが、これはちょっとしたハックです。

public Test (String filename) { 
    this(doChecks(filename), new File(filename)); 
} 

private static Void doChecks(String filename){ 
    if (filename == null) 
     throw new NullPointerException("The String you entered is null."); 
    if (filename.isEmpty()) 
     throw new IllegalArgumentException("The String you entered is empty."); 
    return null; 
} 

public Test (Void dummy, File f) { 
    this(f); 
} 

public Test (File f) { 
    /* implementation here */ 
} 
+0

最初のオプションは、 'init'関数を書いてそれを使うのと同じですか? –

+0

3番目のオプションのコード例を追加しました。 – Antimony

+0

*これは、Javaでは任意の制限のために不可能です。*:制限は恣意的ではないと思います;) – NINCOMPOOP

0

いいえ、thisに電話する前にエラーを確認することはできません。これは仕様によって禁止されています。実際、あなたはそれを必要としませんでした。 new File(filename)に例外をスローします。

編集:私たちはthisまたはコンストラクタでsuper、どちらかthisまたはsuperを使用する場合はActually that is what my constructor with the implementation has, it catches the exception may be thrown by file, so I just add the null exception and use this directly in my second constructor?

public Test (String filename) { 
    this((filename == null || filename.isEmpty()) ? null : new File(filename)); 
} 
+0

これは 'filename.isEmpty()'のときに間違った例外タイプをスローします。 – Antimony

0

は、コンストラクタの最初のステートメントでなければなりません:私はaizen92さんのコメントを見ました。特定のコンストラクタから例外をスローした方が良いでしょう。

public Test (String filename) { 
    this(new File(filename)); 
} 

二コンストラクタはnullを渡すことによって生じたいかなる例外を処理してみましょう。

public Test (File file) { 
    // exception handling code 
    // or new instance creation 
} 
+0

実際には、実装の私のコンストラクタが持っているものですが、例外がファイルによってスローされる可能性があるので、null例外を追加して、2番目のコンストラクタで 'this'を直接使用しますか? –

関連する問題