readonlyフィールド
プログラミングC# p100
最初の一回だけ代入可能なフィールドのことらしい。
using System; class RDOnly { public static readonly int a; static RDOnly() { a = 12; } static void Main(string[] args) { Console.WriteLine("RDOnly.a = {0}", RDOnly.a); RDOnly.a = 24; } }
これをコンパイルするとエラー。
readonly.cs(15,3): error CS0198: 静的読み取り専用フィールドへの割り当てはできません (静的コンストラクタまたは変数初期化子では可)。
書籍中ではstaticフィールドに対してreadonly付けてましたが、インスタンスフィールドに対してもreadonly付けられます。
using System; class RDOnly { public readonly int a; RDOnly() { a = 12; } static void Main(string[] args) { RDOnly rd = new RDOnly(); Console.WriteLine("rd.a = {0}", rd.a); //rd.a = 24; } }
コメントをはずすと同様のエラーが出る。
そういえばと思い出して、Javaでプログラムを書いてみたら、同じ様なことが出来た。
public class ReadOnly { public final int aaa; public ReadOnly() { this.aaa = 12; this.aaa = 24; // コンパイルエラー } public static void main(String[] args) { ReadOnly ro = new ReadOnly(); System.out.println(ro.aaa); } }
Java言語規定 / クラス / 8.3.1.2 finalフィールドによると、
フィールドは,final 宣言できる。この場合,宣言子に変数初期化子を含まなければならない。そうでなければ,コンパイル時エラーが発生する。
ってなんか微妙に違うような。
宣言子に変数初期化子を含まなければならない。っていうのは、
public final int aaa = 12;
みたいなことを言うのではないのかなぁ。
コンストラクタではなく、mainの方で初期化してみる。
public class ReadOnly { public final int aaa; public ReadOnly() { //this.aaa = 12; } public static void main(String[] args) { ReadOnly ro = new ReadOnly(); ro.aaa = 12; System.out.println(ro.aaa); } }
コンパイル結果はこう。
ReadOnly.java:13: final 変数 aaa に値を代入することはできません。 ro.aaa = 12;
インスタンスフィールドは、コンストラクタで初期化しないとダメみたい。
ちなみにstaticフィールドは、static初期化子で初期化しないとダメみたい。
staticフィールドはあんまり使い道なさそうだけど、インスタンスフィールドは何かの役に立つかも。