Java 変数の種類(ローカル・クラス・インスタンス変数)

f:id:nowa0402:20210530191849p:plain
こんにちは。のわです。
今回は、Javaから
『変数名と優先順位』をまとめてみます。


はじめに今回のポイントです

 ・メソッド内に記述された変数は『ローカル変数』と呼ぶ
 ・クラス定義直下、メソッド外に定義された変数をインスタンス変数』『クラス変数』と呼ぶ
 ・インスタンス変数名やクラス変数名はローカル変数名と同一でも構わない
 ・同名の変数名がある場合、変数名だけ記述するとローカル変数として処理される


では、例をあげて、まとめてみます。


例は『下記コードをコンパイル・実行した際何が起きるか』
という内容です。
実際のコードがこちら

【Main.java

public class Main {
    
    static int num = 10; 
    
	public static void main(String[] args) {
        int num = num; 
        System.out.println(num);

 }
}

皆さんこのコードの実行結果はわかりましたか?








私は悩んだ挙げ句、答えを『10』にしました。
結果、見事に間違えました。(泣)

では、解説しながらポイントをまとめてみます。



私が悩んだのは問題コードのこの部分

        int num = num; 

このコードの右辺にある『num』
これを私は

        static int num = 10; 

のnumだと思っていました。


ここで、1つ目のポイントになります。

public class Main {
    
    static int num = 10; 
    
	public static void main(String[] args) {
        int num = num; 
        System.out.println(num);

 }
}

『static int num = 10』はメソッドの外で宣言されています。
このようにクラスの中にあり、メソッドの外で宣言された変数を『メンバ変数』と呼びます。

なお、メンバ変数には2種類あり
『クラス変数』→staticあり
インスタンス変数』→staticなし

で大別されます。

今回はstaticがありなので『クラス変数』となります。


2つ目のポイントです。
このメンバ変数は使うときは『明示的に使うことを記述する』のが大切になります。
つまり『この変数名はクラス変数なんだよ〜』って教えてあげることです。

例えば、先程のクラス変数を使うコードを記述します。

public class Main {
    
    static int num = 10; 
    
	public static void main(String[] args) {
        System.out.println(Main.num);

 }
}

このように、クラス変数を使用する場合は
『クラス名.クラス変数』で記述する必要があります。




では、私が悩んだ、このコードは何を意味しているのか

        int num = num;

これはmainメソッドの中で宣言されている変数となります。
このようにクラスの中にあり、メソッドの中で宣言された変数を『ローカル変数』といいます。

ローカル変数は『記述されたブロック内で有効』な変数です。


上記コードを言葉で表すなら
『ローカル変数numを宣言し、その中にnumを参照代入する』
という意味にまります。


では、右辺のnumは結局どのnumになるのかですが
このnumには何の明示もありません。

ここで3つ目のポイントです。
 ・メンバ変数名とローカル変数名が同一
 ・変数に明示がない

この2つに当てはまる場合、変数は『ローカル変数』として処理されます。

つまり、上記コードは
『自分自身を参照代入』している状態です。

その後にコンソール出力しようとしていますが
自分自身を参照代入している状態 = 初期化が終わっていない状態です
初期化していないもの使用しているコードだと、コンパイルエラーになります。


つまり、答えは『コンパイルエラー』になる。
です。


では、上記コードを私が考えていた『10』にするにはどうすればいいか
右辺のnumをクラス変数だと明示してあげることです。

public class Main {
    
    static int num = 10; 
    
	public static void main(String[] args) {
	    int num = Main.num;
        System.out.println(num);

 }
}


因みに、インスタンス変数だと少し記述が変わります。

public class Main {
    
    int num = 10; 
    
	public static void main(String[] args) {
	    int num = new Main().num;
        System.out.println(num);

 }
}

この場合、一度newでインスタンスを生成しています。
(mainメソッドがstaticなためthisで明示できない)


今回は変数についてまとめてみました。
まとめです。
 ◇変数には大きく分けて『メンバ変数』『ローカル変数』が存在する
 ◇メンバ変数にはインスタンス変数』『クラス変数』があり、その使い分けはstatic有無できまる
 ◇メンバ変数とローカル変数が
   ・同一名である
   ・変数に『this.変数名』や『クラス名.変数名』のように明示がない
  この条件を満たした場合、明示がない変数は『ローカル変数』で処理される


今回も最後まで読んでいただきありがとうございました!!