更新時間:2020-10-27 17:48:11 來源:動力節(jié)點 瀏覽1944次
final修飾符一直是Java基礎(chǔ)知識中非常重要的考點,final關(guān)鍵字可以用來修飾類、變量、方法。final變量不能重新賦值,子類不能覆蓋父類的final方法,final類不能有子類。這些都是非常基礎(chǔ)的考點,但是也是非常重要的內(nèi)容,不容忽視。
1.final修飾成員變量
(1)final修飾的成員變量一旦賦值后,不能被重新賦值。
(2)final修飾的實例Field,要么在定義該Field的時候指定初始值,要么在普通初始化塊或構(gòu)造器中指定初始值。但是如果在普通初始化塊中為某個實例Field指定了初始值,則不能再在構(gòu)造器中指定初始值。
(3)final修飾的類Field,要么在定義該Field的時候指定初始值,要么在靜態(tài)代碼塊中定義初始值。
(4)如果在構(gòu)造器或初始化塊中對final成員變量進行初始化,則不要在初始化之前就訪問該成員的值。
package cn.lsl;
public class FinalTest {
final int a = 5; //直接賦值
final String str; //普通代碼塊中賦值
{
str = "zhangsan";
}
final int b; //構(gòu)造器中賦值
public FinalTest(){
b = 7;
}
final static int c = 8; //直接賦值
final static int d; //靜態(tài)代碼塊中賦值
static{
d = 9;
}
//如果在構(gòu)造器或初始化塊中對final成員變量進行初始化,則不要在初始化之前就訪問該成員的值。
final int age;
{
//System.out.println(age);
age = 22;
System.out.println(22);
}
}
2.final修飾局部變量
(1)系統(tǒng)不會對局部變量進行初始化,布局變量必須要顯示的初始化。所以使用final修飾的局部變量,既可以在定義的時候指定默認值,也可以不指定默認值。
(2)final修飾形參的時候,不能為該形參賦值。
3.final修飾基本數(shù)據(jù)類型變量和修飾引用類型變量的區(qū)別
使用final修飾基本類型的變量,一旦對該變量賦值之后,就不能重新賦值了。但是對于引用類型變量,他保存的只是引用,final只能保證引用類型變量所引用的地址不改變,但不保證這個對象不改變,這個對象完全可以發(fā)生改變。
final修飾的引用類型變量不能被重新賦值,但是可以改變引用變量所引用對象的內(nèi)容。
4.final的“宏變量”
(1)final修飾符的一個重要用途就是“宏變量”。當(dāng)定義final變量時就該為該變量指定了初始值,而且該初始值可以在編譯時就確定下來,那么這個final變量本質(zhì)上就是一個“宏變量”,編譯器會把程序中
所有用到該變量的地方直接替換成該變量的值。
package cn.lsl;
public class FinalTest {
public static void main(String[] args){
final String name = "小明" + 22.0;
final String name1 = "小明" + String.valueOf(22.0);
System.out.println(name == "小明22.0");
System.out.println(name1 == "小明22.0");
}
}
final String name1 = "小明" + String.valueOf(22.0);中調(diào)用了String類的方法,因此編譯器無法再編譯的時候確定name1的值,所以name1不會被當(dāng)成“宏變量”。
5.final修飾方法
用final修飾的方法不能被重寫。用final修飾的類不能有子類。
因為重寫的前提是子類可以從父類中繼承此方法,如果父類中final修飾的方法同時訪問控制權(quán)限為private,
將會導(dǎo)致子類中不能直接繼承到此方法,因此,此時可以在子類中定義相同的方法名和參數(shù),此時不再產(chǎn)生重寫與final的矛盾,而是
在子類中重新定義了新的方法。
6.不可變類
不可變類是指創(chuàng)建該類的實例后,該實例的Field是不可改變的。
如果創(chuàng)建自定義的不可變類,應(yīng)該遵循如下規(guī)則
(1)使用private和final修飾符來修飾該類的Field。
(2)提供帶參數(shù)的構(gòu)造器,用于傳入?yún)?shù)來初始化類里的Field。
(3)僅為該類的Field提供getter方法,不要為該類的Field提供setter方法。
(4)如果有必要,重寫Object類的hashCode和equals方法。
package cn.lsl;
public class Address {
private final String detail;
private final String postCode;
public Address() {
this.detail = "";
this.postCode = "";
}
public Address(String detail, String postCode) {
this.detail = detail;
this.postCode = postCode;
}
public String getDetail() {
return detail;
}
public String getPostCode() {
return postCode;
}
public boolean equals(Object obj){
if(this == obj){
return true;
}
if(obj !=null && obj.getClass() == Address.class){
Address ad = (Address)obj;
if(this.getDetail().equals(ad.getDetail()) && this.getPostCode().equals(ad.getPostCode())){
return true;
}
}
return false;
}
public int hashCode(){
return detail.hashCode() + postCode.hashCode() * 31;
}
}
因為final修飾引用類型變量時,表示這個引用變量不可重新被賦值,但引用類型變量所指向的對象依然可被改變。所以在創(chuàng)建不可變類的時候,如果包含的Field類型是可變的,那么這個不可變類就創(chuàng)建失敗了。
Final修飾符作為Java基礎(chǔ)中的重點內(nèi)容,延伸出來的知識和考點還有很多,本文也只是總結(jié)了一部分比較重要的內(nèi)容,想要全方位學(xué)習(xí)final修飾符的后續(xù)知識,可以觀看本站的Java基礎(chǔ)教程,快速熟練掌握final修飾符的全部用法。
初級 202925
初級 203221
初級 202629
初級 203743