素人プログラマ奮闘記

javaの初心者がAndroidのことを独学で勉強しつつ、メモを残していきます。

final修飾子

final修飾子はクラス、メソッド、メンバ変数の宣言時に付与することがでます。

java初心者の私は今まであまり気にせず適当につけたりしてましたが
ちゃんと勉強しようと思いメモとして残しておきます。

クラス宣言時にfinalを使用する場合


final public class ClassA {
	//finalはpublicの前後どちらでもOKです。
    public void outPutA(){
    	System.out.println("TESTA");
    }
}
--------------------------------------

//エラーになります。
public class ClassB extends ClassA {  

    public void outPutB(){
        System.out.println("TESTB");
    }
}

クラスBがクラスAを継承し、クラスAのサブクラスとなっています。
しかし、クラスAはfinal修飾子を付けて宣言されているので、継承されません。
final修飾子を付与してクラスを宣言するとそのクラスは継承できなくなります。

で?どんな場合に使用するのか?ですが・・・
・サブクラスを作る必要がないと明示的に宣言しておきたい場合
・十分に継承を考慮できていないクラスに宣言しておく
・final宣言しない以上は、final宣言が必要ないようなクラス設計に心がける

まあ、むやみやtらにサブクラスを作れなくするためにロックをかけることですかね?

メソッド宣言時にfinalを使用する場合


 public class ClassA {
    //final指定したメソッド
    final public void outPut(){    
    	//finalはpublicの前後どちらでもOKです。
        System.out.println("TEST");
    }
}
--------------------------------------

//エラーになります。
public class ClassB extends ClassB{
    @Override
    public void outPut(){  
    	//エラーになります。
        System.out.println("TEST");
    }
}

クラスBがクラスAを継承し、クラスAのサブクラスとなっています。
クラスAのoutPutメソッドをオーバーライドしようとしますが
outPutメソッドはfinal修飾子を付与しているためエラーになります。

で?どんな場合に使用するのか?ですが・・・
・メソッドの性質上、オーバーライドさせたくない場合

う~ん、使いどころがまったくわかりません('A`)
どなたか詳しい方教えてくださいm(__)m

メンバ変数宣言時にfinalを使用する場合


public class ClassA {

    //メンバ変数
    final public String mainTitle = "メインタイトル";  //final指定したら初期値の指定は必須
    //メソッド
    public void outPut(){

        final String subTitle = "デモタイトル";  //ローカル変数にも指定可能  

	mainTitle = "Hoge001";  //final指定した変数に値の代入は不可。
	subTitle = "Hoge002";   //final指定した変数に値の代入は不可。

    }
}
mainTitleメンバ変数とsubTitleローカル変数の値を変しようとしていますが
それぞれfinal修飾子を付与しているためエラーになります。

で?どんな場合に使用するのか?ですが・・・
・固定の値を見やすくすく表現したい場合
・変更されたくない変数(定数)を宣言する場合
これはたまにつかいますね、タイマーの間隔とかを定数で宣言したり、あとログ出力時のタイトルを固定にしたりなどなど
一般的に定数を宣言する場合、変数名はすべて大文字で宣言され、
複数の単語をつなげる際は[_]を使用します。(MAIN_TITLEなど)

注意点


public class ClassA {
    
    private String name; //名前
    public String age;	 //年齢
    
    public ClassA(string name) {
    	this.name = name;
    	this.age = 0;
    }
}

public class ClassB {
	
	final public ClassA taro = new ClassA("太郎")
	
	public void Test() {
		taro = new ClassA("次郎"); //NG
		
		taro.age = 1;				//OK
		
	}
}
ClassBでfinal修飾子を付与してClassAクラスのメンバ変数を宣言してます
taroに対してNewを実行するとエラーになります。が、taro.ageの値は変更可能です。

メソッドの引数にfinalを使用する場合


public class classA {
	public void method(final int x, int y) {
		x = 200; // ビルドエラー
		y = 100;
	}
}
methodの引数xには final修飾子が付加されているため
その引数の値は変えられません。ビルドエラーになります。

で?どんな場合に使用するのか?ですが・・・
・引数の値を上書きされたくない場合
(基本型の場合はメソッド内で値を変更したとしてもメソッドを抜けると元に戻ります)

これは結構調べたのですがfinalを付ける派と付けない派で分かれているみたいですね。
いまいち何時が使い時なのかわからないのですが基本引数の値は変更しないように心掛けているため
私としてはfinalを付ける派になるのかもしれません。

inserted by FC2 system