2009-03-24 8 views
7

Javaコンストラクタで最終変数を使用するソリューションはありますか?Javaのコンストラクタの前に最終変数を初期化する

private final String name = "a name"; 

、私はコンストラクタでそれを使用することはできません。 問題は、私は次のように最後のフィールドを初期化する場合ということです。 Javaは最初にコンストラクタを実行し、次にフィールドを実行します。コンストラクタの最後のフィールドにアクセスできるソリューションはありますか?

+1

コンストラクタの値を正しく変更したいと思いますか? – webclimber

+2

私の理解から、これは本当に問題ではないことが判明したので、私は閉会に投票しています。 OPが何をしようとしているのはうまくいくはずです。 –

+1

コンストラクタは、スーパーコンストラクタを呼び出す直前に暗黙的にフィールドの初期化を実行します。 –

答えて

17

私は本当にあなたの質問を理解していません。それ

public class Test3 { 
    private final String test = "test123"; 

    public Test3() { 
     System.out.println("Test = "+test); 
    } 

    public static void main(String[] args) { 
     Test3 t = new Test3(); 
    } 
} 

次のように実行します。

のgetName()はあなたの名前を取得する静的な機能です
$ javac Test3.java && java Test3 
Test = test123 
15

は、例えば、あなたが実際に変数の宣言時に値を知っていれば、それが一定にするより理にかなって、例えば、コンストラクタで

private static final String NAME = "a name"; 
をもちろん

private final String name; 
private YourObj() { 
    name = "a name"; 
} 

を初期化を実行します。

2

この場合、フィールドを「静的」としてマークすることもできます。

+0

静的フィールドのない方法ですか? – Tobias

+0

@Tobiask:なぜ静的なフィールドが必要ないのですか? – sfossen

+0

これは不変なので、静的にすることもできます。 –

1

この場合、静的にすることもできます。 Javaの規約では、このような定数をALL_CAPSに指定します。

1
private static final String name = getName(); 

+0

getName()が定数を返す以外は何もしない場合、この構文に注意してください。 getName()によって使用されるロジックが初期化されていない可能性があります。 – DJClayworth

3

staticとマークすると、コンストラクタで使用できるようになりますが、最後に変更したため変更できません。

private static final String name = "a_name"; 

でも静的initブロックを使用することができます。

private static final String name; 

static { name = "a_name"; } 

コンストラクタ内の値を変更しようとすると、デフォルト値を割り当てることができないか、それを最終的にしなければなりません。

private String name = "a_name"; 
Foo(String name) 
{ 
    this.name = name; 
} 

または

private final String name; 

Foo(String name) 
{ 
    if(s == null) 
     this.name = "a_name"; 
    else 
     this.name = name; 
} 
0
Javaは、まずフィールドを、コンストラクタを実行している間、私は、コンストラクタでそれを使用することはできません

...

これは正しくありません、フィールド最初に評価されます。そうしないと、コンストラクタのメンバーの初期値にアクセスできませんでした。なぜなら、初期化されていないからです。この作業ない:

public class A { 
    protected int member = 1; 
    public A() { 
     System.out.println(member); 
    } 
} 

キーワード最終は、単にそれがそうでなければ他のメンバーとして扱われ、部材の定数をマークします。

編集:には、のコンストラクタの値を設定しようとしていますか?メンバーはfinalと定義されていると不変なので、これはうまくいかないでしょう。

+0

技術的には、フィールドの初期化ロジックを(暗黙的に)実行するコンストラクタです。 –

+0

まあ、大丈夫です。それにもかかわらず、フィールドは最初に評価されます。 – soulmerge

2

別のpossiblityは、インスタンス初期化子ブロック内のフィールドを初期化することである。

public class Foo { 
     final String bar; 

     { 
       System.out.println("initializing bar"); 
       bar = "created at " + System.currentTimeMillis(); 
     } 

     public Foo() { 
       System.out.println("in constructor. bar=" + bar); 

     } 

     public static void main(String[] args) { 
       new Foo(); 
     } 
} 
5

我々は質問から離れて取得しています。

はい、private final変数を使用できます。例:

public class Account { 
    private final String accountNumber; 
    private final String routingNumber; 

    public Account(String accountNumber, String routingNumber) { 
     this.accountNumber = accountNumber; 
     this.routingNumber = routingNumber; 
    } 
} 

これは、アカウントクラスが2つの文字列、アカウント、およびルーティング番号に依存していることを意味します。 Accountクラスが構築されると、これらのクラス属性の値を設定しなければならず(MUST)、新しいクラスを作成せずにこれらの値を変更することはできません(MUST)。

'final'修飾子は、属性を不変にします。

+2

基本的には、コンストラクタの値を設定する際には1回の作業しかありません。コンストラクターが完了すると、属性は定数になります。 –

+2

「最終的な変数値に値を代入できません」というエラーが表示されます。 –

関連する問題