第9章 java修飾子

修飾子の種類やその挙動について説明します。

HOMEPAGE

java修飾子


※ 修飾子は上から定義する順に並んでいます。

修飾子 説明
アクセス修飾子 アクセス修飾子を指定することにより、メンバ変数を他のクラスから参照できないなどを指定できるようになります。
static メンバ変数がインスタンス変数ではなく、クラス変数であることを表します。
final finalをつけると変数に一度値が生成されるとその値を変更できず定数として扱われます。
transient シリアライズすべきでないメンバ変数を表します。
volatile メンバ変数に対して、コンパイラが何らかの最適化を施すことを防止します。

※ 修飾子は上から定義する順に並んでいます。

修飾子 説明
アクセス修飾子 アクセス修飾子を指定することにより、メソッドを他のクラスから参照できないなどを指定できるようになります。
static メソッドがインスタンスメソッドではなく、クラスメソッドであることを表します。
abstract 処理を実装しないメソッド(抽象メソッド)を生成したい時に使用します。
final finalを使用した場合、そのメソッドはサブクラスでオーバーライドすることができません。
native C言語など他の言語で記述されたプログラムをJavaプログラム内で使用したい時に使います。使用したいプログラムにnativeを付け定義します。
synchronized スレッドを複数同時に走らせる際に同じデータに対し複数のメソッドが呼び出される場合があります。そのような場合、安全にメソッドが実行されるためにsynchronizedを使用します。


アクセス修飾子

指定できるアクセス修飾子を以下に記載します。
クラス定義時に指定できるアクセス修飾子は「public」と「指定無し(デフォルト)」のみです。

アクセス修飾子 クラス メンバ変数 メソッド コンストラクタ
public
protected ×
指定無し(デフォルト)
private ×

アクセス修飾子 自パッケージ 他パッケージ
自クラス サブクラス 他クラス サブクラス 他クラス
public
protected ×
指定無し(デフォルト) × ×
private × × × ×

例:1 [AccessTest.java]
package Jsample;
public class AccessTest {
	public void a(){
		System.out.println("public");
	}
	protected void b(){
		System.out.println("protected");
	}
	void c(){
		System.out.println("修飾子なし");
	}
	private void d(){
		System.out.println("private");
	}

	public static void main(String[] args){
		AccessTest test = new AccessTest();

		test.a();
		test.b();
		test.c();
		test.d();
	}
}
実行結果
public
protected
修飾子なし
private



例:2 [Television.java]
package JSample;
public class Television{
	private int channelNo;

		private void setChannel(int newChannelNo){
			channelNo = newChannelNo;
			System.out.println("新しいChannelNo=" + channelNo);
			}
}
[JSample9_2.java]
package JSample;
public class JSample9_1{
	public static void main(String args[]){
		Television tv1 = new Television();
		tv1.setChannel(1);
	}
}
実行結果 (コンパイルの段階でエラーとなります。)
pic here
この例では、TelevisionクラスのprivateメソッドのためJSampleクラスからはアクセスできません。
そのためコンパイルエラーとなります。


メンバ変数、メソッドを定義する際、static修飾子が付与されたものをクラス変数クラスメソッド、static修飾子が付与されていないものをインスタンス変数インスタンスメソッドといいます。
mainメソッドはインスタンスを生成する前に実行する必要があるため、static修飾子を付けて定義しています。

static変数とはクラスに1つだけ存在する変数です。
オブジェクトごとに存在するインスタンス変数とは異なり、オブジェクトを生成しなくてもアクセスできます。
static変数はクラス単位で管理したいときに便利な変数です。

例:
クラス変数の参照方法を例示します。
[ExClass.java]

package JSample;
class ExClass{
	static int standardSize;
	void setSize(int num) {
		standardSize = num;
	}
}

[JSample9_2.java]
class JSample9_2 {
	public static void main(String[] args) {
		ExClass ins1 = new ExClass();
		ins1.setSize(100);
		
		ExClass ins2 = new ExClass();
		ins2.setSize(300);
		
		System.out.println(ins1.standardSize);
		System.out.println(ins2.standardSize);
		System.out.println(ExClass.standardSize);
	}
}
実行結果
300
300
300

クラス変数は、インスタンス間で値を共有するため、一番最後に設定された300が表示されます。

staticメンバーを利用する場合の注意点を、以下にまとめておきます。
(1)staticメソッドからthisにはアクセスできない。
staticメソッドでは、いわゆるインスタンスはありませんので、当然、インスタンスを示すthisにもアクセスできません。
(2)staticフィールドの利用は限定的。
staticフィールドは、インスタンスフィールドとは違い、内容を変更した場合にもすべてのインスタンスに影響します。

例:
クラス変数、クラスメソッドの参照方法を例示します。
[JSample9_3.java]
package JSample;
class JSample9_3 {
	static String classA = "クラス変数classA";
	
	static void classB() {
		System.out.println("クラスメソッドclassB");
	}
	
	public static void main(String[] args) {
		System.out.println(JSample9_3.classA);
		JSample9_3.classBS();
	}
}
実行結果
クラス変数classA
クラスメソッドclassB


練習

問題 [JEx9_1.java]

public class JEx9_1 {
   public static void main(String[] args) {
      Cat cat1 = new Cat(3);
      Cat cat2 = new Cat(5);
      System.out.println(cat1.age);
   }
}

class Dog {
   static int age;
	
   public Cat(int age) {
      this.age = age;
   }
}
実行結果を選択してください
  1. 「3」と表示
  2. 「5」と表示
  3. 何も表示されない
  4. コンパイルエラー
  5. 実行時エラー

問題 [JEx9_2.java]
問題1のプログラムを修正してください


戻る