3

私は次のfinalようなアクセス修飾子を持ついくつかのフィールドを持つクラスに取り組んでいます:final textFieldそして私は何らかの理由でそれらに割り当てることを許可されています。それらをに変更するとstatic final、それらに何も割り当てることができなくなります(最初に行うべきだったように、それらが最終的なものであると文句を言います)。なぜこれが起こっているのか考えはありますか?

最初のケースの例:

final LabelField label_title;

label_title = new LabelField(
        "Press the button to launch the speed test",
        LabelField.FIELD_HCENTER);
4

5 に答える 5

17

コンストラクターでフィールドを割り当てることはできfinalますが、コンストラクターでフィールドを割り当てることはできませんstatic final。いかなる場合でも、コンストラクターの静的フィールドを変更しないでください。

于 2012-10-18T15:14:38.560 に答える
7

フィールドがとして定義されfinalている場合、オブジェクトの構築時にフィールドを初期化する必要があります。つまり、コンストラクター内でフィールドに値を割り当てることができます。

staticフィールドはクラス自体に属します。つまり、クラスごとに1つです。したがってstatic final、オブジェクトごとに1つであるコンストラクターでは、フィールドを割り当てることはできません。

それがあなたにとって理にかなっていることを願っています!

于 2012-10-18T15:26:48.747 に答える
5

最終メンバーの値は変更できません。ただし、コンストラクターで最終インスタンスフィールドを初期化することは許可されています。これはクラスメンバーには許可されていません。次のスニペットは、許可されているものと許可されていないものを示しています。

public class Final {

    final static Integer INT1;  // compile error
    final static Integer INT2 = new Integer(2);
    final Integer int3;
    final Integer int4 = new Integer(4);

    public Final() {
        int3 = new Integer(3);
        int3 = new Integer(3); // compile error
    }
}
于 2012-10-18T15:18:27.437 に答える
3

からJLS - final fields:-

フィールドはfinalと宣言できます(§4.12.4)。クラス変数とインスタンス変数(静的フィールドと非静的フィールド)の両方をfinalとして宣言できます。

空白のfinal(§4.12.4)クラス変数が、それが宣言されているクラスの静的初期化子(§8.7)によって明確に割り当てられていない場合(§16.8)、コンパイル時エラーになります。

空白の最終インスタンス変数は、それが宣言されているクラスのすべてのコンストラクター(§8.8)の最後に確実に割り当てられる必要があります(§16.9)。そうしないと、コンパイル時エラーが発生します。

したがって、静的初期化ブロックでフィールドJLSを割り当てる必要があることを明確に指定します。static finalコンストラクターでそれらを割り当てることはできません。

したがって、static finalフィールドがある場合は、その場で初期化するか、を使用しStatic Initializer Blockて初期化する必要があります。

さらに、final後でどこでも割り当てを変更しない限り、コンストラクターでフィールドを割り当てることができます。

于 2012-10-18T15:14:57.047 に答える
1

静的フィールドはクラスに属します。クラスは、クラスがロードされた直後に初期化されます(必要があります)。つまり、最終的な場合は初期化する必要があります(値を割り当てる必要があります)。

コンストラクターは、誰かがクラスをインスタンス化する必要があるときに呼び出されます。ここで、コンストラクターでその静的finalフィールドの値を変更すると、その値を変更(または再割り当て)しようとしていることを意味します。

ただし、静的初期化子(static { /* assign value here */ })でこれを行うことは問題ありません。これは、クラスの初期化を目的としています。

于 2012-10-18T15:22:53.333 に答える