スコープとは
スコープとは、一言で言えば変数やメソッドの見える範囲のことを指します。
Java のスコープには、大きく分けてローカル変数のスコープとprivate, publicのようなアクセス修飾子によるスコープがあります。簡単なサンプルコードを確認しながら、Javaのスコープについて理解を深めていきましょう。
ローカル変数のスコープ
ローカル変数は、メソッドの中でのみ有効な変数です。
変数の有効範囲はブロック{}で囲まれた範囲となり、例えば if ブロック内で宣言した変数は、if ブロックの中の処理でしか使用できません。
次のサンプルコードは、メソッドの処理の先頭で変数 str を宣言した時の変数の有効範囲を確認するコードです。
メソッドレベルのブロック{}で宣言したローカル変数は、宣言行った次の行から、そのメソッドの処理の最後までが有効範囲となります。
public static void main(String[] args) {
String str = “Hello Java”; // 変数 str を宣言
System.out.println(“str=” + str);
if ( args.length == 0 ) {
// メソッドレベルのブロックで宣言された変数は if ブロックでも使用可能
str = “Ruby”;
System.out.println(“str=” + str);
}
}
逆に、if や for などのブロック内で宣言された変数は、そのブロック内でのみ使用可能です。
public static void main(String[] args) {
if ( args.length == 0 ) {
// メソッドレベルのブロックで宣言された変数は if ブロックでも使用可能
String str = “Ruby”; // 変数 str を宣言
System.out.println(“str=” + str);
}
// if ブロック内で宣言されたブロックを抜けると使用不可になるため、
// 次の行はコンパイルエラーになる
System.out.println(“str=” + str);
for (int i = 0; i < 10; i++) {
// 当然、別のブロックで宣言された変数を参照することもできないため、
// 次の行もコンパイルエラーになる
System.out.println(“str=” + str);
}
}
アクセス修飾子
次は public, private などのアクセス修飾子について解説します。
Java には次の4つのアクセス修飾子があり、その指定によってクラスやメソッドが、どの範囲からアクセス可能であるかを決定します。
- public:最も公開範囲が広いアクセス修飾子。すべてのクラスからアクセスができる。
- protected:自身のクラスと、このクラスを継承したサブクラスからアクセスできる。
- 指定なし:アクセス修飾子を省略するとパッケージプライベートとなり、自分のクラスと同じパッケージからアクセスできる。
- private:最も公開範囲が狭いアクセス修飾子。自分のクラスのみからアクセスができる。
この4つのアクセス修飾子をクラス・メソッド・変数に付けることで、それぞれのオブジェクトの公開範囲を設定します。
では、アクセス修飾子の種類と公開範囲が分かったところで、実際にクラス・メソッド・変数にアクセス修飾子を指定するサンプルコードを作成してみましょう。
クラス
クラスには通常 public と指定なしの2のアクセス修飾子が指定できます。ただし、内部クラス(インナークラスとも呼ぶ)の場合は、 protected および private のアクセス修飾子も指定できます。
・public
public class SampleClass1 {
}
・指定なし(パッケージプライベート)
class SampleClass2 {
}
・protected (内部クラス)
class SampleClass3 {
protected class ProtectedClass {
public void output() {
System.out.println( "ProtectedClass" );
}
}
}
・private(内部クラス)
class SampleClass4 {
private class PrivateClass {
public void output() {
System.out.println( "PrivateClass" );
}
}
}
メソッド
メソッドにアクセス修飾子を付けることで、そのメソッドの公開範囲を指定します。
// すべての範囲に公開する public メソッド
public void sampleMethod1() {
}
// アクセス修飾子を省略すると同日パッケージ内から参照可能
void sampleMethod2() {
}
// 自身とサブクラスからアクセス可能な protected
protected sampleMethod3() {
}
// 自身のクラス内からのみアクセス可能な private
private sampleMethod4() {
}
メソッドのアクセス修飾子はクラスの公開範囲を超えることができません。
例えば public 修飾子をメソッドに指定したとしても、クラスのアクセス修飾子が省略されている場合は、そのメソッドは同一パッケージ内のみからアクセスできません。
package com.example.package1;
class SampleClass {
// このメソッドは「SampleClass」と同一パッケージからしかアクセスできない
public void sampleMethod1() {
}
}
変数
クラスのインスタンス変数にもアクセス修飾子を指定でき、公開する範囲を指定します。
class SampleClass {
public String field1;
String field2;
protected String field3;
private String field4;
}
まとめ
ローカル変数のスコープや、アクセス修飾子について解説してきました。本記事で解説した内容を以下にまとめますので、おさらいしておきましょう。
- ローカル変数の有効範囲はブロック{}で囲まれた範囲である
- ブロックを抜けるとローカル変数は使用できない
- アクセス修飾子にはpublic, protected 指定なし, privateの4つがある
- public は全体に公開
- protected は自身とサブクラスに公開
- 指定なし は同一パッケージ内に公開(パッケージプライベート)
- private は自身のクラス内のみに公開
【関連記事】
▶【Java】クラス名とメソッド名の取得方法解説【サンプル有】
変数にはローカル変数以外にも、インスタンス変数や static 修飾子が付いた静的な変数などがあります。インスタンス変数はインスタンス毎に異なった値を持つことができ、インスタンスメソッド(staticではないメソッド)から参照することができます。逆に、static 修飾子が付いた変数はクラス毎に1つの値を保持できインスタンスメソッドまたは static なメソッドから変数の値が参照できます。