1. 定数

他の多くのプログラミング言語には定数、つまり値を変更できない変数がありますPi通常、これらは、1 年の月の数や日数など、ある種の基本的なものに使用されます。とはいえ、原則として、プログラマは、必要と判断した場合には、任意の変数を定数にすることができます。

では、Java で不変変数 (定数) を宣言するにはどうすればよいでしょうか? これには特別なキーワードがあります: final。不変変数の作成は、通常の変数の作成と同じように見えます。final唯一の違いは、次のように変数の型の前に単語を記述する必要があることです。

final Type name = value;

変数に別の値を割り当てようとするとfinal、プログラムはコンパイルできません。

変数finalは宣言時に初期化する必要があります (値を割り当てる必要があります)。この規則には例外が 1 つあります。それは、静的クラス変数の初期化をコンストラクターに移動できることです。ただし、これについてはレベル 10 で学びます

キーワードの数を減らすために、Java 開発者はこの単語をfinal定数の宣言以上の目的で使用します。finalメソッドやクラスにも適用できます。として宣言されたメソッドはfinalオーバーライドできません。また、 として宣言されたクラスはfinal継承できません。

修飾子finalは、ローカル変数、メソッド パラメータ、クラス フィールド、静的クラス変数などの変数の前に追加できます。

final変数名の前は、その変数への変更に対する単なる保護であることに注意してください。変数にオブジェクトへの参照が格納されている場合でも、オブジェクトは変更できます。

例:

final int[] data = {1, 2, 3, 4, 5, 6};

data = {6, 7, 8, 9};

data[0] = 0;
data[1] = 0;
data[2] = 0;
配列を作成します。

これは許可されません。変数dataは として宣言されていますfinal

しかし、これならできます。
そしてこれも。

グローバル定数

プログラム内でグローバル定数を宣言することにした場合は、静的クラス変数を作成し、それらをpublicおよび にする必要がありますfinal。このような変数の名前には特別なスタイルがあり、すべて大文字で書かれ、単語の区切りにはアンダースコア文字が使用されます。

例:

class Solution
{
   public static final String SOURCE_ROOT = "c:\\projects\\my\\";
   public static final int DISPLAY_WIDTH = 1024;
   public static final int DISPLAY_HEIGHT = 768;
}


2. 変数のシャドウイング

前に述べたように、同じメソッド内で同じ名前の複数のローカル変数を作成することはできません。さまざまな方法でそれが可能です。

ただし、おそらくご存じないこともあります。インスタンス変数とローカル メソッド変数は同じ名前を持つことができます。

例:

コード 可変可視性
public class Solution
{
   public int count = 0;
   public int sum = 0;

   public void add(int data)
   {
     sum = sum + data;
     int sum = data * 2;
     count++;
   }
}


count
count, sum
count, sum
count, sum
count, sum, data
count, sum, data
count, sum, data
count, sum, data
count, sum

このaddメソッドでは、 という名前のローカル変数を宣言しましたsum。メソッドが終了するまで、インスタンス変数をシャドウ (またはマスク)しますsum

そうですね、それはある意味予想通りだと思います。しかし、話はこれで終わりではありません。インスタンス変数がローカル変数によってシャドウされている場合でも、メソッド内でインスタンス変数を参照する方法がまだあることがわかります。これを行うには、thisキーワードを名前の前に書きます。

this.name

名前の競合が正常に解決された例を次に示します。

コード 可変可視性
public class Solution
{
   public int count = 0;
   public int sum = 0;

   public void add(int data)
   {
     int sum = data * 2;
     this.sum = this.sum + data;
     count++;
   }
}


this.count
this.count, this.sum
this.count, this.sum
this.count, this.sum
this.count, this.sum, data
this.count, this.sum, data, sum
this.count, this.sum, data, sum
this.count, this.sum, data, sum
this.count, this.sum

count および変数は、キーワードのsum 有無にかかわらず、どこでも使用できますthissum ローカル変数がインスタンス変数をシャドウする行ではsum、キーワードsum を使用してのみインスタンス変数にアクセスできますthis

インスタンス変数ではなく静的クラス変数がシャドウされている場合は、キーワードではなくクラス名を使用してアクセスする必要がありますthis

ClassName.name

例:

コード 可変可視性
public class Solution
{
   public static int count = 0;
   public static int sum = 0;

   public void add(int data)
   {
     int sum = data * 2;
     Solution.sum = Solution.sum + data;
     count++;
   }
}

Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum, data
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum

 クラス名をプレフィックスとして使用しても使用しなくても、どこからでもcount および静的変数にアクセスできます。ローカル変数がインスタンス変数をシャドウする行では、接頭辞として 使用する場合にのみインスタンス変数にアクセスできます。sumSolutionsumsumsumSolution



3.forループ内の変数

そして、小さいながらも興味深い事実がもう 1 つあります。

forループ内など、変数が特別な方法で宣言される場所もあります。

for通常、ループには括弧内にカウンター変数があることを思い出してください。そして、この変数の可視性はどうなるでしょうか? 結局のところ、それはループの本体にはありません。それは全体のメソッドですか?か否か?

正解は、「forループのヘッダーで宣言された変数は、ループの本体ループのヘッダーforでのみ表示されます」です。

例:

コード 可変可視性
public static void main(String[] args)
{
   int a = 0;

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   System.out.println("end");
}


a
a
a, i
a, i
a, i
a
a
a

したがって、いつでもコード内でループを次々に記述し、同じ名前のカウンター変数を使用できます。これにより問題は発生しません。

例:

コード 可変可視性
public static void main(String[] args)
{
   int a = 0;

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   System.out.println("end");
}


a
a
a, i
a, i
a, i
a
a
a, i
a, i
a, i
a
a
a