Java中static可以修飾類叨吮、變量、方法甚至可以構(gòu)成靜態(tài)塊瞬矩,讓我們來(lái)了解下它們各自的使用以及加載順序吧茶鉴。
基本用法
static關(guān)鍵字修飾類
java里面用static修飾內(nèi)部類,普通類是不允許聲明為靜態(tài)的景用,只有內(nèi)部類才可以涵叮。
public class StaticTest {
//static關(guān)鍵字修飾內(nèi)部類
public static class InnerClass{
InnerClass(){
System.out.println("============= 靜態(tài)內(nèi)部類=============");
}
public void InnerMethod() {
System.out.println("============= 靜態(tài)內(nèi)部方法=============");
}
}
public static void main(String[] args) {
//直接通過(guò)StaticTest類名訪問(wèn)靜態(tài)內(nèi)部類InnerClass
InnerClass inner=new StaticTest.InnerClass();
//靜態(tài)內(nèi)部類可以和普通類一樣使用
inner.InnerMethod();
}
}
如果沒(méi)有用static修飾InterClass,則只能new 一個(gè)外部類實(shí)例伞插。再通過(guò)外部實(shí)例創(chuàng)建內(nèi)部類割粮。
static關(guān)鍵字修飾方法
修飾方法的時(shí)候,其實(shí)跟類一樣媚污,可以直接通過(guò)類名來(lái)進(jìn)行調(diào)用:
public class StaticMethod {
public static void test() {
System.out.println("============= 靜態(tài)方法=============");
};
public static void main(String[] args) {
//方式一:直接通過(guò)類名
StaticMethod.test();
//方式二:通過(guò)對(duì)象調(diào)用
StaticMethod fdd=new StaticMethod();
fdd.test();
}
}
static關(guān)鍵字修飾變量
被static修飾的成員變量叫做靜態(tài)變量穆刻,也叫做類變量,說(shuō)明這個(gè)變量是屬于這個(gè)類的杠步,而不是屬于是對(duì)象氢伟,沒(méi)有被static修飾的成員變量叫做實(shí)例變量榜轿,說(shuō)明這個(gè)變量是屬于某個(gè)具體的對(duì)象的。
我們同樣可以使用上面的方式進(jìn)行調(diào)用變量:
public class StaticVar {
private static String name="java技術(shù)棧";
public static void main(String[] args) {
//直接通過(guò)類名
StaticVar.name;
}
}
static關(guān)鍵字修飾代碼塊
靜態(tài)代碼塊在類第一次被載入時(shí)執(zhí)行朵锣,在這里主要是想驗(yàn)證一下谬盐,類初始化的順序。
父類靜態(tài)變量
父類靜態(tài)代碼塊
子類靜態(tài)變量
子類靜態(tài)代碼塊
父類普通變量
父類普通代碼塊
父類構(gòu)造函數(shù)
子類普通變量
子類普通代碼塊
子類構(gòu)造函數(shù)
//首先我們定義一個(gè)父類
public class Father {
// 父類靜態(tài)變量
public static String str1 = "father static str";
// 父類普通變量
public String str2 = "father common str";
// 父類靜態(tài)代碼塊
static {
System.out.println("father static block");
}
// 父類普通代碼塊
{
System.out.println("father common block");
}
// 父類構(gòu)造方法
public Father() {
System.out.println("father constructor");
}
}
//然后定義一個(gè)子類
public class Child extends Father {
// 子類靜態(tài)變量
public static String str1 = "child static str";
// 子類普通變量
public String str2 = "child common str";
// 子類靜態(tài)代碼塊
static {
System.out.println("child static block");
}
// 子類普通代碼塊
{
System.out.println("child common block");
}
// 子類構(gòu)造方法
public Child() {
System.out.println("child constructor");
}
}
// 測(cè)試
public static void main(String[] args) {
new Child();
}
輸出為:
father static block
child static block
father common block
father constructor
child common block
child constructor
原理講解
上圖為jvm運(yùn)行時(shí)數(shù)據(jù)區(qū)诚些,靜態(tài)變量存放在方法區(qū)中飞傀,并且是被所有線程所共享的。
方法區(qū)中包含的都是在整個(gè)程序中永遠(yuǎn)唯一的元素诬烹,如類信息砸烦、static變量等。
舉例
定義一個(gè)類绞吁,包含靜態(tài)變量幢痘、靜態(tài)方法。
public class Person{
//靜態(tài)變量
static String firstName;
String lastName;
public void showName(){
System.out.println(firstName+lastName);
}
//靜態(tài)方法
public static void viewName(){
System.out.println(firstName);
}
public static void main(String[] args) {
Person p =new Person();
Person.firstName = "張";
p.lastName="三";
p.showName();
Person p2 =new Person();
Person.firstName="李";
p2.lastName="四";
p2.showName();
}
}
//輸出家破。張三颜说、李四
從內(nèi)存的角度看一下:
從上面可以看到,我們的方法在調(diào)用靜態(tài)方法汰聋、變量的時(shí)候门粪,是從方法區(qū)調(diào)用的,但是調(diào)用普通變量是從堆內(nèi)存中調(diào)用的烹困,堆內(nèi)存中的成員變量lastname是隨著對(duì)象的產(chǎn)生而產(chǎn)生玄妈,隨著對(duì)象的消失而消失。靜態(tài)變量是所有線程共享的髓梅,所以不會(huì)消失拟蜻。
小結(jié)
特點(diǎn)
- static是一個(gè)修飾符,用于修飾成員女淑。(成員變量,成員函數(shù))static修飾的成員變量稱之為靜態(tài)變量或類變量辜御。
- static修飾的成員被所有的對(duì)象共享鸭你。
- static優(yōu)先于對(duì)象存在,因?yàn)閟tatic的成員在類的加載時(shí)初始化擒权。
- static修飾的成員多了一種調(diào)用方式袱巨,可以直接被類名所調(diào)用,(類名.靜態(tài)成員)碳抄。
- static修飾的數(shù)據(jù)是共享數(shù)據(jù)愉老,對(duì)象中的變量的是特有的數(shù)據(jù)。
成員變量和靜態(tài)變量的區(qū)別
- 生命周期的不同:
成員變量隨著對(duì)象的創(chuàng)建而存在隨著對(duì)象的回收而釋放剖效。
靜態(tài)變量隨著類的加載而存在隨著類的消失而消失嫉入。
- 調(diào)用方式不同:
成員變量只能被對(duì)象調(diào)用焰盗。
靜態(tài)變量可以被對(duì)象調(diào)用,也可以用類名調(diào)用咒林。(推薦用類名調(diào)用)
- 別名不同:
成員變量也稱為實(shí)例變量熬拒。
靜態(tài)變量稱為類變量。
- 數(shù)據(jù)存儲(chǔ)位置不同:
成員變量數(shù)據(jù)存儲(chǔ)在堆內(nèi)存的對(duì)象中垫竞,所以也叫對(duì)象的特有數(shù)據(jù)澎粟。
靜態(tài)變量數(shù)據(jù)存儲(chǔ)在方法區(qū)(共享數(shù)據(jù)區(qū))的靜態(tài)區(qū),所以也叫對(duì)象的共享數(shù)據(jù)欢瞪。
靜態(tài)使用時(shí)需要注意的事項(xiàng):
- 靜態(tài)方法只能訪問(wèn)靜態(tài)成員活烙。(非靜態(tài)既可以訪問(wèn)靜態(tài),又可以訪問(wèn)非靜態(tài))
- 靜態(tài)方法中不可以使用this或者super關(guān)鍵字遣鼓。
- 主函數(shù)是靜態(tài)的