Developer

【はじめてのJava】変数のスコープ3(ローカル変数)【オブジェクトとクラス編】
2021.10.31
Lv1

【はじめてのJava】変数のスコープ3(ローカル変数)【オブジェクトとクラス編】

はじめてのJava

このシリーズでは、初めてJavaやプログラミングを勉強する方向けに、Javaによるプログラミングの基礎を説明していきます。
目標レベルは、Javaの資格試験の一つである「Oracle Certified Java Programmer, Silver」(通称Java Silver)に合格できる程度の知識の習得です。
はじめてJavaやプログラムに触れる方にもできるだけわかりやすい解説を心がけていきます。


オブジェクトとクラス編

オブジェクトとクラス編では、Javaを扱う上で非常によく出てくる「オブジェクト」や「クラス」について扱っていきます。

前回は「static変数のスコープ」について扱いました。

今回は「変数のスコープ」について紹介します。


目次


変数のスコープ

 変数のスコープ とはその変数を利用可能な範囲のことです。

変数は宣言したからと言ってすべての箇所で使えるわけではありません。

また、ローカル変数については、同じ変数という名前がついている「インスタンス変数」「static変数」とは大きく異なるものです。
ローカル変数のスコープを考える際には、インスタンス変数やstatic変数と異なる視点で考える必要があります。

詳しく見ていきましょう。


ローカル変数のスコープ

ローカル変数は宣言されたブロック内でのみ利用可能な変数です。ですので、 宣言されたブロックが終わると利用できません 

例えば、以下の図のようなSmartPhoneクラスがあったとします。callPhoneメソッドを見てみると、引数minutesがあります。このminutesはローカル変数です。

minutesがローカル変数ということは、callPhoneメソッドが終わると使用することができません。

callPhoneメソッドの外側(例えば下の図のようなanswerThePhoneメソッド内)ではminutesは使用できません。

 

このほかにも、ローカル変数は 宣言した後で利用できるようになる という特徴があります。

このような特徴から、ローカル変数のスコープには特に注意が必要です。


宣言の位置に注意

ローカル変数の場合は 宣言したブロック内でも、宣言前は利用できません 
これはインスタンス変数やstatic変数と全く異なる点です。Javaの試験では必須の内容です。

以下のような場合、コンパイルエラーとなります。

class Sample{
  void method(){
    String message = "hello";
    System.out.println(message); //OK

    System.out.println(message2); //NG。ローカル変数は宣言よりも前では利用できない。
    String message2 = "good night";
  }
}

メソッドブロックで宣言した場合

メソッドブロックで宣言されたローカル変数は そのメソッド内でのみ利用できます。

例えば、以下のような場合、コンパイルエラーとなります。

class Sample{

  void method(){
    String message = "hello";
    System.out.println(message); //OK
  }

  void otherMethod(){
    System.out.println(message); //NG。ローカル変数は宣言されたブロックの外では利用できない。
  }
}


【コラム】異なるブロックで同じ名前のローカル変数を定義した場合

ローカル変数はそのメソッド内でのみ利用できる、ということは、逆に言えば、メソッドが異なれば、同じ名前のローカル変数を定義可能です。

例えば、以下のように別々のメソッドでそれぞれ「message」という名前の変数を定義可能です。
この時  2つのmessage変数は全く別のもの であることに注意してください。

class GreetingRobot{
  void greetingA(){
    String message = "hello";
    System.out.println(message); //OK。helloが表示される
  }

  void greetingB(){
    String message = "good night";
    System.out.println(message); //OK。good nightが表示される
  }
}

class MainSample{
  public static void main(String[] args){

    GreetingRobot robo = new GreetingRobot(); //インスタンス化
    robo.greetingA(); //helloが表示される
    robo.greetingB(); //good nightが表示される

    //greetingA()のmessageとgreetingB()のmessageは別物なので
    //greetingB()を実行してもしてもgreetingA()のmessageはhelloのまま。
    robo.greetingA(); //helloが表示される。
    
  }
}


ほかのクラス内での利用について

インスタンス変数やstatic変数については、アクセス修飾子を付けることで他のクラス内で利用ができるかどうかを設定することができました。
しかし、そもそもローカル変数は他のクラスでの利用は想定されていないので ローカル変数にアクセス修飾子を付けるとコンパイルエラー です。

class Sample{
  void method(){
    public String publicMessage = "hello"; //NG
    protected String protectedMessage = "hello"; //NG
    String message = "hello"; //OK
    private String privateMessage = "hello"; //NG
  }
}


まとめ

ローカル変数は宣言したブロック内でのみ利用できる
同じブロック内で宣言されたローカル変数でも、宣言前は利用できない
他のクラス内ではローカル変数を使うことはできない

次回

次回もローカル変数のスコープについて扱います。


はじめてのJavaシリーズの目次はこちら
オブジェクトとクラス編はこちら


java 11 の練習問題一覧はこちら
はじめてのJavaシリーズの練習問題一覧はこちら