java final static_Java基础之final、static关键字
一、前言
關于這兩個關鍵字,應該是在開發工作中比較常見的,使用頻率上來說也比較高。接口中、常量、靜態方法等等。但是,使用頻繁卻不代表一定是能夠清晰明白的了解,能說出個子丑演卯來。下面,對這兩個關鍵字的常見用法做點總結記錄,方便之后的回顧以及突擊知識點。
二、關鍵字 final
final,一如字面意思 “最終的”,大體在 Java 中表示 “不可變的”。可用來修飾類、方法、方法參數以及變量。
1、修飾類
final 在修飾類的時候,代表的是此類不能被繼承。也就是說如果一個類確定不會被繼承使用,則可以設計成 final類型的。典型的例子就是 String 類。
2、修飾方法
final 修飾的方法,能被繼承,但是不能重寫。可以重載。
3、修飾方法參數
final 在修飾方法參數的時候,表示的是在執行方法的內部,不能夠去改變參數的值。但是如果是引用對象,是可以改變應用對象的屬性值。
4、修飾變量
final 在修飾變量,代表的是不可變,也即是常說的 “常量”。 final 在修飾的時候,允許一次賦值,之后在生命周期類,不允許對其進行修改。
修飾變量存在兩種情況:基本類型的數據 和? 對象數據。在修飾基本類型數據的時候,值是不可變的。在修飾對象數據的是,對象的引用是不可改變的,但是,可以修改對象內部的屬性值。
final 修飾的變量必須在使用前進行初始化,一種方式是在聲明的時候就給出默認值。還有一種就是通過構造方法去設置。
5、代碼示例
package com.cfang;
import java.util.Calendar;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Slf4jpublic classT3 {public static voidmain(String[] args) {//-- 修飾變量
final int b = 0;/**
* 編譯報錯:The final local variable b cannot be assigned. It must be blank and not using a compound assignment*/
//b = 2;//-- 修飾方法參數
DemoCls cls = newDemoCls();
cls.setAge(10);
log.info("democls age : {}", cls.getAge());int a = 10;
sayHello(a, cls);
log.info("after call sayHello, democls age : {}", cls.getAge());
}private static void sayHello(final inta, final DemoCls cls) {/**
* 編譯報錯:The final local variable a cannot be assigned. It must be blank and not using a compound assignment*/
//a = 11;//cls = new DemoCls();
cls.setAge(11);
}
}
@DataclassDemoCls{private intage;
}//-- 修飾方法
@Slf4jclassPerson {public final voidsaySth() {
log.info("i am person");
}
}
@Slf4jclassMale extends Person{/**
* 編譯出錯 : Cannot override the final method from Person
* 修飾的方法不能夠被重寫*/
//public final void saySth() {//log.info("i am male");//}
public final voidsaySth(String msg) {
log.info("i am male");
}
}
其中,修飾方法參數,如果是引用對象,是可以改變對象的屬性值,這一點也很好理解:cls 是引用變量,final 修飾引用變量,只是限定了此引用變量 cls 的引用不能改變,而實際引用的對象的本身的值是可以進行修改的。文字語言組織可能不是很清晰,如下圖所示,一目了然的就知道說要表述的意思了。
三、關鍵字 static
static,靜態的。在 Java 中,static 通常可被用于修飾 變量、方法以及代碼塊。
1、修飾變量
static 修飾的變量,叫做靜態變量。static 變量被所有類對象共享,在內存中僅一份,隨著類的初始化而被加載。與之對應的非靜態變量,是屬于每個實例對象本身,內存中存在多份,相互間不影響。
2、修飾方法
static 修飾的方法,叫做靜態方法。調用靜態方法,不依賴于實例對象就可以進行訪問,所以,靜態方法是沒有 this的。由于此特性以及非靜態方法依賴于實例對象調用,所以靜態方法中是不能夠直接使用非靜態的成員屬性和方法。與之相反的是,非靜態方法是可以直接訪問使用靜態成員變量和方法。同樣的,靜態方法也是沒有 super 的。可以一句話總結下:由于 static 和具體的實例對象無關,而 this、super和具體的實例對象息息相關,所以,static 和 this、super 勢如水火,一如白天與黑夜。
3、修飾代碼塊
static 修飾代碼塊,在類初始化加載的時候,會按照 static 塊的順序進行加載,并且,生命周期內,只加載一次。基于此特性,可以設計優化程序的性能,一些只需要一次性初始化加載的內容,就可以放在 static 塊中進行。
4、代碼示例
package com.cfang;
import lombok.extern.slf4j.Slf4j;
@Slf4jpublic classT4 {private static inta;private static intb;private static intc;static{
log.info("init value a");
a= 10;
}
{/**
* 普通代碼塊,依賴于實例對象*/log.info("init value c");
c= 12;
}public static voidmain(String[] args) {//-- 靜態方法調用非靜態
/**
* 不可直接訪問*/
//sayHello1();
newT4().sayHello1();//-- 靜態方法直接調用
sayHello();//-- 靜態代碼塊初始化資源
log.info("value a : {}", a);
log.info("value b : {}", b);
log.info("value c : {}", c);
}private static voidsayHello() {
log.info("say hello");
}private voidsayHello1() {
log.info("say hello1");//-- 非靜態方法直接調用
sayHello();
}static{
log.info("init value b");
b= 11;
}
}
5、static 常見誤區
package com.cfang;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Slf4jpublic classT5 {private static int a = 10;public static voidmain(String[] args) {newT5().printVal();//-- The field DemoCls01.b is not visible
DemoCls01.b;
}private voidprintVal() {int a = 11;
log.info("value a : {}", this.a);
}
}
@DataclassDemoCls01{private static intb;
}
5.1、static 的 this
上述代碼中,最終運行 printVal 方法,輸出的結果是 :value a : 10? 。 其實這也很好理解: this 指代的當前對象,而通過 new T5().printVal() 調用的話,this 指代的就是當前新創建的實例對象,static 修飾的變量本身是被所有類對象所共享的,而 printVal 方法中 a 屬于局部變量,跟 this 實例對象并沒有關聯。所以,輸出的就是 10。
5.2、static 與 可見性
static 并不能改變變量或者方法的可見性。上述代碼中,main 方法中,DemoCls01.b 會編譯報錯。
5.3、static 與 局部變量
Java規范中,明確說明了 :static 關鍵字不可修飾局部變量。
四、總結
final 和 static ,聯合使用修飾屬性表示一旦給值,就不可修改,并且可以通過類名訪問;修飾方法,表示該方法不能重寫,可以在不new對象的情況下調用。
突然想到,接口?interface 中,成員變量的默認修飾符為 public static final,方法的默認修飾符 public abstract 。
總結
以上是生活随笔為你收集整理的java final static_Java基础之final、static关键字的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 针眼是什么引起的(针眼是什么)
- 下一篇: 电脑桌面软件怎么卸载(电脑桌面软件变大怎