1. 程式人生 > >Final淺談

Final淺談

return 地址 sys 方法 效果 拷貝 pen img extend

Final可以修飾類,也可以修飾方法和變量,還可以修飾參數,接下來就淺談下Final的意義:

1、修飾類

被Final 修飾的類是不能被繼承的,默認final修飾的類的方法也是final類型的。從字面就可以看出,final意為“最終的,不可更改的”,在用final修飾類之前,要確認是否該類永遠都不要被繼承,又或是出於安全的考慮;

2、修飾方法

被final修飾的方法不能被子類重寫,但存在一種情況:父類的final方法是private,這樣子類可以有同樣的方法,但要清楚,這是兩個單獨的方法,並非重寫;

例:

public class FinalTest {
private final void getName(){
System.out.println("蘇東坡");
}
}

public class FinalTest2 extends FinalTest {
private void getName(){
System.out.println("佛印");
}
public static void main(String[] args) {
FinalTest2 t2=new FinalTest2();
t2.getName();
}
}

這兩個getName方法其實是兩個不同的方法,最後輸出的結果是“佛印”。

3、修飾變量

被final修飾的變量要麽在申明的時候就賦值,要麽在類的構造方法中賦值,一旦賦值就不可更改

技術分享圖片

final修飾的變量和普通變量的區別:

public static void main(String[] args) {
String a="hello2";
final String b="hello";
String c="hello";
String d=b+2;
String e=c+2;
System.out.println(a==d);
System.out.println(a==e);
}

輸出的結果是true,false;為什麽呢,當final變量是基本數據類型和String類型,在編譯期就已經i確認變量的值,所以編譯器會把它當做編譯期常量來用,等到運行時取的是對應的值,而普通變量需要在運行時通過鏈接來進行。但是只有在編譯期確切知道值的變量,編譯器才會做這樣的優化,如果只有在運行時才能確認值,即使是final修飾的變量也沒有這樣的效果,如:

public static void main(String[] args) {
FinalTest2 t2=new FinalTest2();
String a="hello2";
final String b=t2.getValue();
String c="hello";
String d=b+2;
String e=c+2;
System.out.println(a==d);
System.out.println(a==e);
}
public String getValue(){
return "hello";
}

這個輸出結果是false,false.

final修飾的引用變量指向的對象不可變,但對象的內容可以改變,因為它指向的是對象的地址

技術分享圖片

4、修飾參數

被final修飾的參數,在方法中不能被修改,但參數裏面的內容是可以改的:

public static void main(String[] args) {
FinalTest2 t2=new FinalTest2();
StringBuffer buffer=new StringBuffer("修改前的");
t2.changeValue(buffer);
System.out.println(buffer);

}
public void changeValue(final StringBuffer buffer){
buffer.append("修改後的");
System.out.println(buffer);
}

打印的結果是兩次“修改前的修改後的”,另補充:java中采用的是值傳遞,也就是實參和形參指向的是同一個對象,對於基本數據類型變量,直接對變量的值作了拷貝,當形參指向另一個對象的時候,實參並沒有改變;

public static void main(String[] args) {
FinalTest2 t2=new FinalTest2();
StringBuffer buffer=new StringBuffer("修改前的");
t2.changeValue(buffer);
System.out.println(buffer);
}
public void changeValue( StringBuffer buffer){
buffer=new StringBuffer("修改後的");
System.out.println(buffer);
}

這個打印結果是“修改後的,修改前的”;

Final淺談