arrow_back

変数のスコープ

ローカル変数とフィールド

「変数にはローカル変数フィールドがあるよ。ローカル変数はこれまで使ってきた変数のこと。 フィールドについてはまた後で」
「で、スコープなんだけど、一言で言えば"変数の効力が及ぶ範囲"という意味になるのかな」
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button) findViewById(R.id.button);
        button.setText("Hello!");
    }
「例えばこんなプログラムだったら、変数buttonを使えるのは、宣言より下の行になる」
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button.setText("Hello!");
        Button button = (Button) findViewById(R.id.button);
    }
「こうすると、buttonが宣言される前に変数を使っているからエラーになるってこと。 この場合は、アプリを実行する前にAndroid Studioがエラーを表示するよ。って……ハルキ?」
「ハルキ……エイゴキライ……ニホンゴ……スキ!」
「まだやってたの……おーい、戻ってこーい」
「あいたたたた! 脇腹! 脇腹をつねるのはやめてっ! いろんな意味でダメージがっ!」
「いま言ってたことわかった?」
「イタタタタ……その辺りはなんとなく。まだないものは使えない。って話でいいのかな」
「よしよし。じゃあ次ね。この場合はどうなると思う?」
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int value1 = 5;
                button.setText(String.valueOf(value1));
            }
        });
        value1 = 2;
        button.setText(String.valueOf(value1));
    }
「え、value1は5だからボタンを押したら5が表示されて…… けど、setOnClickListenerのあとにvalue1は2になってるから……あれ?」
「慌てなくていいよ。正解は『value1に2を再代入しているところはスコープの外だからエラーになる』」
「Java言語では、波括弧で括った範囲を ブロックと呼ぶんだけど、 変数はそれを宣言した場所か、それより下のブロックからしか扱う(アクセスする)ことはできないんだよ。 こんな感じかな」
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // ブロックA

        int value = 1;  // ブロックA に含まれるブロックで有効

        {
            // ブロックB

            value = 2;  // ○ アクセスできる

            int value2 = 3; // ブロックB に含まれるブロックで有効
        }

        value2 = 4; // × ブロックAからブロックB内で宣言された変数にはアクセスできない
    }
「あれ。じゃあ、なんでOnClickListenerからtextViewにアクセスできなかったの?」
「あー、あれには、また別の規則があると思って」
「ややこしいなぁ……」
「結局、AndroidじゃなくてJava言語の話だからね…… 何度も言ってるけど、AndroidをやりたいならJava言語の勉強をきちんとしていかないとね」

画面の部品をフィールドに移動

「ここまでは"ローカル変数"の話をしてたけど、最後に"フィールド"を説明したら、いよいよ電卓を作っていくよ」
「フィールドって? インクを?」
「変数の話! フィールドはスコープがこれまでより広いんだよ」
public class MainActivity extends AppCompatActivity {

    TextView textView;
    EditText editText;
    Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.textview);
        editText = (EditText) findViewById(R.id.edittext);

        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                textView.setText(editText.getText().toString());
            }
        });

    }
}
「変数の宣言を上の方に書くんだね」
「できたら実行してみて」
「……うん。入力した内容が表示される。ちゃんと動いてるよ!」
OnClickListenerをフィールドに移動
「じゃあ次、あと、OnClickListenerのところがややこしいって言ってたよね。 OnClickListenerもフィールドにしてしまおう」
public class MainActivity extends AppCompatActivity {

    TextView textView;
    EditText editText;
    Button button;

    View.OnClickListener buttonListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            textView.setText(editText.getText().toString());
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.textview);
        editText = (EditText) findViewById(R.id.edittext);

        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(buttonListener);

    }
「ふむふむ。こっちはbuttonListenerって名前をつけるんだね。 = に続いて……これは前に書いてあった部分をそのままコピー……と」
「コピーするのはいいけど、 最後の});のところ、全部コピーしちゃわないように気をつけるんだよ。 括弧の対応にはくれぐれも気をつけて」
「はーい。できたよ。実行実行と……」
「……」
「なにかおかしなことあった?」
「……いや、ちゃんと動いてるんだけど。プログラムいっぱい変えても動きが特に変わらないと、 ちょっとむなしいなーって」
「言いたいことはわかるよ。 ただね。"ややこしいな"とか、"読みにくいな"って感じたときに、すっきりと書き直すのはすごく大事なことだから。 自分がわかりづらいと感じたところは、もっといい書き方がないか考える癖をつけていこうね!」
最終更新日: 2015/09/03