技術とか戦略とか

IT技術者が技術や戦略について書くブログです。

java:引数で渡した参照型変数をメソッド内で変更する書き方について

参照型変数を引数としてメソッドに渡し、呼び出し先のメソッドの中でその参照型変数に変更を入れた場合、呼び出し元でもその変更内容を参照することができます。
ソースコードで言うと、以下のような形で呼び出し元に影響を与えることができます。
(isDisplay[0]の変更は呼び出し元にも反映されます。実行すると、"Hello World!"が出力され、"Error!"は出力されません。)
 
public class HelloWorld {
  public static void main(String[ ] args){

    boolean isDisplay = {false,false};

    getIsDisplay(isDisplay);

    if (isDisplay[0]) {
      System.out.println("Hello World!");
    }
    if (isDisplay[1]) {
      System.out.println("Error!");
    }

  }

  public static void getIsDisplay(boolean isDisplay) {
    isDisplay[0] = true;
  }
}
 
このような書き方は、C言語のレガシーなコードではよく見かけますが、javaではあまり見かけることがないと思います。
レガシーな現場に入ったことが無い方は、見慣れていない、違和感がある、と感じる方が多いと思います。
 
javaでは、以下のように戻り値により呼び出し元に影響を与える書き方の方が主流です。
 
public class HelloWorld {
  public static void main(String[ ] args){

    boolean[] isDisplay = {false,false};

    isDisplay[0] = getIsDisplay();

    if (isDisplay[0]) {
      System.out.println("Hello World!");
    }
    if (isDisplay[1]) {
      System.out.println("Error!");
    }

  }

  public static boolean getIsDisplay() {
    return true;
  }
}
 
ビジネスロジックを知り尽くしている場合は、前者のようにメソッドに参照型変数を渡してメソッドの中で好きに変更させる形にした方が楽にコーディングできます。
しかし、ビジネスロジックをよく知らない担当者がソースコードを調査したり改修したりする場合、後者のように戻り値を通して呼び出し元に影響を与える形にしないと、読む必要があるソースコードの範囲が広がり、調査・改修が困難になります。
今回の例で言うと、"isDisplay[1]"に変更が入っていないことを知るために、前者のコードではメソッドの中まで見る必要がありますが、後者のコードではメソッドの中まで見る必要はありません。
 
現在の開発現場では、複数の担当者が入れ替わり立ち替わりでソースコードを改修し続けるのが主流ですので、後者の書き方の方が望まれます。
現行のソースコードが既に前者の形で書かれているのであれば、それに合わせた方が良い場合もありますが、そうではないなら後者の書き方で書くべきでしょう。