Javaでは,
フィールド変数→明示的に初期化しなければデフォルト値(0, falseなど)に初期化される
ローカル変数→明示的に初期化せずに使用するとコンパイルエラーになる
という規則があることを知りました.何か理由があってこのような設計になっていると思うのですが,その理由は何でしょうか?推測でも構いませんので教えていただけると助かります.
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
身も蓋もない言い方をすると「パフォーマンス」「プログラムの論理的正当性をどういうふうに保証するかの方針」「デバッグの困難さの軽減」「実装の実現性」といった色々な言語仕様上の考慮点のバランスをとった結果ということではないかと思います。
以下自分の推測を大雑把に述べてみます。
- ローカル変数
初期化せずにアクセスするということはバグと考えられるのですが、それを防ぐために
(A)プログラマーの責任にゆだね、システムはそれについて何もしない
(B)宣言したとたんに無条件に初期化してしまう仕様にする
(C)初期化する前にアクセスしているかどうかをコンパイラーがチェックしもしそうならエラーにする
といったいくつかの選択肢が考えられます。C言語のような古い言語では(A)の方針を取っていましたが、Javaではあらゆるエラーに対して例外処理を行える点を保証したかったのでメモリー破壊を引き起こす(A)は許容できませんでした。(B)(C)のうちパフォーマンスを無駄に落とさずしかもフロー解析技術の発達により可能になったという事情で(C)を採用しました。
- フィールド
本当ならローカル変数と同じようにしたほうがよいのかも知れません。しかしフィールドの初期化をしてからでないとアクセスできないとすると、コンストラクターが完了する前に全てのフィールドに値を設定しなければならないということになります。クラス・インスタンスの表現の幅をもたせたいのでフィールドの宣言場所で必ず初期値を指定するというやりかたを強制するのは許容できませんでした。コンストラクターや初期化ブロック内である一定の順番で初期化するという方法も十分正当だと考えられるからです。さらにフィールドの初期化中に他の初期化済みのフィールドを参照できるという仕様も(そうしたほうがずっと柔軟な初期化が行えるので)採用されました。こうなるとローカル変数のように完全にフロー解析するのは大変困難なことになります。そこで技術的にも仕様を明確にするためにもあらかじめシステムが自動的にオブジェクト(クラス、インスタンス)を確保したとたんにALL 0に初期化するという方針をとりました。(うがった見方をすれば初期化中にガベージコレクションが発生した際に中身がゴミの状態のオブジェクトの存在を許容したくなかったという技術的な理由もあったかも知れません)
以上は推測なので不正確な点があるかも知れませんのでその点はご容赦ください。
投稿2016/10/25 16:32
編集2016/10/26 10:42総合スコア18392
0
”フィールド変数→明示的に初期化しなければデフォルト値(0, falseなど)に初期化される”
これはコンパイラで実行形式を作成されるときに実体が生成されます。
”ローカル変数→明示的に初期化せずに使用するとコンパイルエラーになる”
これはそのローカル変数を含むメソッドが呼ばれた時に初めて実メモリー上に割り付けられ、メソッドが終わると消滅(破棄)されます。そのため割り付けする際にどんな変数か?をコンパイラに教えないと、どう割り付けるかが分かりません。
なぜこんな構造になっているか?
それは有効にメモリーを活用するため、必要な時にそれを割り付ける事でメモリーの再利用やプログラムのメモリー占有を減らすためです。
投稿2016/10/25 16:35
総合スコア3747
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。