CodeGym /Java Blog /ランダム /Java スコープ
John Squirrels
レベル 41
San Francisco

Java スコープ

ランダム グループに公開済み
国には国境があり、独自の法律があることは誰もが知っています。その国の法律は国境内で適用されます。また、国内には、例えば学校や博物館など、独自のローカルルールを設けている組織もあります。国の法律に抵触するものではなく、指定された組織の枠内でのみ活動します。プログラミングでも同様です。プログラミング、特に Java 言語には、「スコープ」という用語があります。これは、変数やメソッドなどの特定のデータが機能するプログラムの領域を指します。この記事では、Java の変数のスコープとは何か、またそれらを定義する方法について説明します。

Java スコープ一般

変数とメソッドのスコープを分離する必要があるのはなぜですか? 実際、プログラムが非常に大きくなり、1 つまたは別の変数を追跡することが困難になる場合があります。さらに、大規模なプロジェクトでは、変数の目的を明確にするために、変数に明確な名前を付けることが望ましいです。スコープを使用すると、具体的には、プログラムの異なる部分に同じ名前の異なる変数を含めることができます。このようなコードは保守しやすく、読みやすいです。Java スコープは、プログラム内の特定の変数またはメソッドにアクセスできる場所を定義します。簡単に言うと:
  • メソッド内で宣言された変数は、宣言の先頭からメソッドの末尾 (メソッド スコープ) まで表示されます。
  • コード ブロック内で宣言された変数は、そのコード ブロックの終わりまで存在します。
  • メソッドの引数である変数はメソッドの終了まで存在します。
  • クラス/オブジェクト変数は、それを含むオブジェクトの存続期間中存在します。それらの可視性は特別なアクセス修飾子によって制御されます。
  • 静的クラス変数は、プログラムの実行中に常に存在します。それらの可視性はアクセス修飾子によっても決まります。

メソッドレベルのスコープ

引数を含め、メソッド内で宣言された変数には、そのメソッドの外部からはアクセスできません。メソッド内で宣言されたすべての変数は、宣言の先頭からメソッドの最後まで表示されます。メソッド変数のスコープの例を次に示します。

public class JScopeTest1 {


   public static void main(String[] args) {

       System.out.println(myMethod(5));
       System.out.println(myMethod(17));

   }
   public static int  myMethod(int arg) {
       int secondArg = 100; //local method variable
       return secondArg + arg;
   }
}
ここには、ローカル変数またはメソッド引数であるSecondArg があります。この変数をmyMethodメソッドの外で、または宣言される前に使用することはできません。変数が関数の引数である場合、その変数はこのメソッドの本体全体で表示されます。上の例では、そのような引数が 2 つあります。myMethod の arg と main メソッドの args です。

クラスレベルの範囲

クラスレベルのスコープ (インスタンス変数) — クラスで宣言された変数は、そのクラスのすべてのメソッドで使用できます。アクセス修飾子 (パブリックまたはプライベート) に応じて、クラスの外部からアクセスできる場合があります。したがって、変数がクラス変数の場合、その変数は特定のオブジェクトにバインドされ、このクラスのオブジェクトが存在する限り存在します。オブジェクトがない場合、変数のコピーはありません。変数は、その前に宣言されたか後に宣言されたかに関係なく、クラスのすべてのメソッドから参照できます。各オブジェクトには、他のオブジェクトから独立した独自の変数があります。静的メソッドから変数にアクセスすることはできません。

コード例


public class Student {
   
//class level variables
   public String surname;
   String name;
   String secondName;
   private Long birthday; // Long instead of long is used by Gson/Jackson json parsers and various orm databases

   public Student(String surname, String name, String secondName, Date birthday ){
       this.surname = surname;
       this.name = name;
       this.secondName = secondName;
       this.birthday = birthday == null ? 0 : birthday.getTime();
   }

   @Override
   public int hashCode(){
       //TODO: check for nulls
       //return surname.hashCode() ^ name.hashCode() ^ secondName.hashCode() ^ (birthday.hashCode());
       return (surname + name + secondName + birthday).hashCode();
   }
   @Override
   public boolean equals(Object other_) {
       Student other = (Student)other_;
       return (surname == null || surname.equals(other.surname) )
               && (name == null || name.equals(other.name))
               && (secondName == null || secondName.equals(other.secondName))
               && (birthday == null || birthday.equals(other.birthday));
   }
}
SurnamenameSecondName、およびbirthdayはインスタンス変数です。

ブロックスコープ

変数がコードのブロック内で定義/宣言されている場合、その変数はコードのそのブロックの終わりまで存在します。通常、このような変数は、変数が定義されている中括弧の間に存在します。非常に多くの場合、ブロック スコープはループ変数になる可能性があります。forループ条件で宣言された変数は、事前に定義していない限り、ループの外ではアクセスできません。

public class JScopeTest2 {
   public static void main(String[] args) {
       for (int i = 0; i < 10; i++) {
           int sum = 0;
           sum = sum + i;
       }
      
       int sum = 1;
       System.out.println(sum);
   }
}
first sum 変数と i 変数はどちらもループ内で宣言されており、このループの外には存在しません。ただし、2 番目の合計はループの外で宣言されているため、この特定の変数が出力されます。

静的変数

変数が静的として宣言されている場合 (static キーワードでマークされている場合)、そのクラスが存在する限り変数は存在します。通常、JVM は、静的変数が初期化される最初の使用時にクラスをメモリにロードします。

import java.util.Date;

public class Student {
   public static int today = 2022;
   String surname;
   String name;
   String secondName;
   Long birthday; // Long instead of long is used by Gson/Jackson json parsers and various orm databases

   public Student(String surname, String name, String secondName, Date birthday ){
       this.surname = surname;
       this.name = name;
       this.secondName = secondName;
       this.birthday = birthday == null ? 0 : birthday.getTime();
   }

 
   public static void main(String[] args) {
       System.out.println(today);
   }

}
静的なtoday変数を使用するためにStudentクラス の新しいインスタンスを作成しないでください。ここでは「2022」と印刷されます。

アクセス修飾子

Java には、メソッドまたは変数へのアクセスを制限する 4 つのアクセス修飾子があります。これらはメソッド内ではなくクラス内で使用できます。
  • privateは最も制限的な修飾子です。これは、メソッドと変数へのアクセスを、それらが宣言されたクラスに制限します。クラス外の特定のメソッドまたは変数を使用する必要がない場合は、private を使用します。Java では通常、クラス変数はプライベートです。

  • アクセス修飾子が指定されていない場合、メソッドまたは変数はデフォルトの修飾子を受け入れます。デフォルトでは、現在のパッケージからのアクセスのみが許可されます。

  • protected修飾子を使用すると、パッケージ外の子クラスを通じてアクセスしない限り、現在のパッケージ内からのみメソッドまたは変数へのアクセスが許可されます。

  • publicは最も制限の少ない修飾子です。これにより、宣言されたクラスだけでなく、外部からもクラス、メソッド、変数にアクセスできるようになります。この修飾子は本当に頻繁に使用されます。

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION