一、final類不能被繼承 ,如java
public final class Test1 {}編程
public class Test2 extends Test1{}這裏會報錯函數
因此final類就沒有子類, 在設計類時候,若是這個類不須要有子類,類的實現細節不容許改變,而且確信這個類不會被擴展,那麼就設計爲final類。.net
二、 final方法不容許子類覆蓋,也就是說不容許子類去修改父類的方法
使用final方法的緣由有二:
第1、把方法鎖定,防止任何繼承類修改它的意義和實現。
第2、高效。編譯器在遇到調用final方法時候會轉入內嵌機制,大大提升執行效率。
例如:設計
package Test;對象
public class Test1 {
public static void main(String[] args) {
}
public void f1() {
System.out.println("f1public");
}
//沒法被子類覆蓋的方法
public final void f2() {
System.out.println("f2final");
}
public static void f3() {
System.out.println("f3public static");
}
private void f4() {
System.out.println("private");
}
}繼承
package Test;get
public class Test2 extends Test1 {
public void f1(){
System.out.println("Test1父類方法f1被子類覆蓋!");
}
public static void main(String[] args) {
Test2 t=new Test2();
t.f1();
t.f2(); //調用從父類繼承過來的final方法
t.f3(); //調用從父類繼承過來的方法
// t.f4(); //調用失敗,沒法從父類繼承得到,這個會報錯
}
}編譯器
輸出:編譯
Test1父類方法f1被子類覆蓋!
f2final
f3public static
三、final常量
package Test;
public class Test3 {
private final String S = "final實例變量S";
private final int A = 100;
public final int B = 90;
public static final int C = 80;
private static final int D = 70;
public final int E; //final空白,必須在初始化對象的時候賦初值
// public final static int F; //出錯,必須賦初值
public static int F;
private static int G;
public static String H;
private static String I;
public Test3(int x) {
E = x;
System.out.println("x="+x);
System.out.println("E="+E);
}
/**
* @param args
*/
public static void main(String[] args) {
Test3 t = new Test3(2);
//t.A=101; //出錯,final變量的值一旦給定就沒法改變
//t.B=91; //出錯,final變量的值一旦給定就沒法改變
//t.C=81; //出錯,final變量的值一旦給定就沒法改變
//t.D=71; //出錯,final變量的值一旦給定就沒法改變
System.out.println(t.A);
System.out.println(t.B);
System.out.println(t.C); //不推薦用對象方式訪問靜態字段
System.out.println(t.D); //不推薦用對象方式訪問靜態字段
System.out.println(Test3.C);
System.out.println(Test3.D);
// System.out.println(Test3.E); //出錯,由於E爲final空白,依據不一樣對象值有所不一樣.
System.out.println(t.F);//不推薦用對象方式訪問靜態字段
System.out.println(t.G);//不推薦用對象方式訪問靜態字段
System.out.println(Test3.F);
System.out.println(Test3.G);
System.out.println(t.H);//不推薦用對象方式訪問靜態字段
System.out.println(t.I);//不推薦用對象方式訪問靜態字段
System.out.println(Test3.H);
System.out.println(Test3.I);
Test3 t1 = new Test3(3);
System.out.println(t1.E); //final空白變量E依據對象的不一樣而不一樣
}
private void test() {
System.out.println(new Test3(1).A);
System.out.println(Test3.C);
System.out.println(Test3.D);
}
public void test2() {
final int a; //final空白,在須要的時候才賦值
final int b = 4; //局部常量--final用於局部變量的情形
final int c; //final空白,一直沒有給賦值.
a = 3;
//a=4; 出錯,已經給賦過值了.
//b=2; 出錯,已經給賦過值了.
}
}
輸出結果:
x=2
E=2
100
90
80
70
80
70
0
0
0
0
null
null
null
null
x=3
E=3
3
四、final參數
當函數參數爲final類型時,你能夠讀取使用該參數,可是沒法改變該參數的值。
public class Test4 {
public static void main(String[] args) {
new Test4().f1(2);
}
public void f1(final int i) {
//i++; //i是final類型的,值不容許改變的.
System.out.print(i);
}
}
輸出:2
五、 static和final一塊用
對於變量,表示一旦給值就不可修改,而且經過類名能夠訪問。
對於方法,表示不可覆蓋,而且能夠經過類名直接訪問。
對於一些容器類型(好比,ArrayList、HashMap)的實例變量,不能夠改變容器變量自己,但能夠修改容器中存放的對象,這一點在編程中用到不少。
package Test;
import java.util.ArrayList;
public class TestStaticFinal {
private static final String strStaticFinalVar = "aaa";
private static String strStaticVar = null;
private final String strFinalVar = null;
private static final int intStaticFinalVar = 0;
private static final Integer integerStaticFinalVar = new Integer(8);
private static final ArrayList<String> alStaticFinalVar = new ArrayList<String>();
private void test() {
System.out.println("-------------值處理前----------\r\n");
System.out.println("strStaticFinalVar=" + strStaticFinalVar + "\r\n");
System.out.println("strStaticVar=" + strStaticVar + "\r\n");
System.out.println("strFinalVar=" + strFinalVar + "\r\n");
System.out.println("intStaticFinalVar=" + intStaticFinalVar + "\r\n");
System.out.println("integerStaticFinalVar=" + integerStaticFinalVar + "\r\n");
System.out.println("alStaticFinalVar=" + alStaticFinalVar + "\r\n");
//strStaticFinalVar="哈哈哈哈"; //錯誤,final表示終態,不能夠改變變量自己.
strStaticVar = "哈哈哈哈"; //正確,static表示類變量,值能夠改變.
//strFinalVar="呵呵呵呵"; //錯誤, final表示終態,在定義的時候就要初值(哪怕給個null),一旦給定後就不可再更改。
//intStaticFinalVar=2; //錯誤, final表示終態,在定義的時候就要初值(哪怕給個null),一旦給定後就不可再更改。
//integerStaticFinalVar=new Integer(8); //錯誤, final表示終態,在定義的時候就要初值(哪怕給個null),一旦給定後就不可再更改。
alStaticFinalVar.add("aaa"); //正確,容器變量自己沒有變化,但存放內容發生了變化。這個規則是很是經常使用的,有不少用途。
alStaticFinalVar.add("bbb"); //正確,容器變量自己沒有變化,但存放內容發生了變化。這個規則是很是經常使用的,有不少用途。
System.out.println("-------------值處理後----------\r\n");
System.out.println("strStaticFinalVar=" + strStaticFinalVar + "\r\n");
System.out.println("strStaticVar=" + strStaticVar + "\r\n");
System.out.println("strFinalVar=" + strFinalVar + "\r\n");
System.out.println("intStaticFinalVar=" + intStaticFinalVar + "\r\n");
System.out.println("integerStaticFinalVar=" + integerStaticFinalVar + "\r\n");
System.out.println("alStaticFinalVar=" + alStaticFinalVar + "\r\n");
}
public static void main(String args[]) {
new TestStaticFinal().test();
}
}
輸出:
-------------值處理前----------
strStaticFinalVar=aaa
strStaticVar=null
strFinalVar=null
intStaticFinalVar=0
integerStaticFinalVar=8
alStaticFinalVar=[]
-------------值處理後----------
strStaticFinalVar=aaa
strStaticVar=哈哈哈哈
strFinalVar=null
intStaticFinalVar=0
integerStaticFinalVar=8
alStaticFinalVar=[aaa, bbb]