ローカル変数のスコープを最小限にする

EFFECTIVE JAVA 第2版 (The Java Series)

EFFECTIVE JAVA 第2版 (The Java Series)

Effective Java 項目45 ローカル変数のスコープを最小限にする  のまとめ。

スコープは狭い方がいい、ということはよく言われている。 ここではコードの可読性と保守性が向上する為と書かれていて、 その技法が紹介されている。

使う直前に書く。

ローカル変数のスコープを最小限にする最も協力な技法は、ローカル変数が初めて使用された時に宣言することです。 (page.203)

while文よりfor文を使う

whileループは、ループ変数が宣言出来ないため、forループを使用すべし。 ループ変数というのは、↓のようなよくみるコードの変数iのことを言っている。

for (int i = 0; i < list.size() ; i++) {
    doSomething(i);
}
  • よくわかってない →解決!

このループ変数は、こんな風に複数宣言することも出来る。

for (int i = 0, n = expensiveComputation(); i < n ; i++) {
    doSomething(i);
}

2つのループ変数iとnを持っており、どちらも正確に正しいスコープを持っています。 2番目の変数nは、最初の変数の上限を保持するのに使用されていて、 ループ毎に冗長な計算を行うコストを回避しています。 一般に、ループ検査がメソッド呼び出しを伴い、そのメソッド呼び出しがループごとに同じ結果を返すことが保証されている場合に、 このイデオムを使用すべきです。 (page.205)

例で書かれているexpensiveComputation()メソッドが複数のループで呼ばれても同じ結果を返すときに、 このイデオムを使用すべき、と言っている?

→ここで言ってる「ループ毎に」ていうのは、繰り返す1回目…2回目のそれぞれのこと言ってると思われる。(というか、ループという単語の意味を間違って認識してたかも。)

expensiveComputation()メソッドが返す値が、繰り返す度に同じ結果を返すものなら、この書き方をしたら良いという意味だ。 日本語難しいな…( ´_`)

for (int i = 0 ; i < expensiveComputation() ; i++) {
    doSomething(i);
}

単純にコレ↑でいいという話ではない? →うん、ダメ。

--- 2014/12/20 add. 知り合いのプログラマの人に教えてもらえた!

上のようにループ変数にexpensiveComputation()の結果をいれない場合、 ループする都度、expensiveComputation()が呼ばれるらしい。 というわけで試してみる。

   public static void main(String[] args) {
        for (int i = 0; i < expensiveComputation(); i++) {
                doSomething(i);
        }
    }

    private static int expensiveComputation() {
        System.out.println("expensiveComputation.");
        return 3; //適当.
    }

【実行結果】

expensiveComputation.
loop count=0
expensiveComputation.
loop count=1
expensiveComputation.
loop count=2

となり、ループの度に呼ばれてた。。 もちろんeffective javaにかかれていた、ループ変数に入れておく例では、 1回しか呼ばれてなかったです。

やっとわかりました。ありがとうございました!


  • 誤字?(´・_・`)?

たとえば、224頁を参照してください。 (page.203)

204頁の間違えかな?? 224頁でそれらしいのが見つからない。。 正誤表*1にも記載がないようだけど、なんか認識違う??