static關鍵字的特色java
用來修飾類的成員-修飾成員變量的稱之爲類變量(靜態變量),修飾成員方法的稱之爲類方法(靜態方法)。(屬性拿static修飾完以後就不叫屬性了,他也就不屬於任何對象了,而是屬於多個對象共享的,就叫類變量或靜態變量,方法也同樣)bash
當類被加載的時候就會被加載,優先於對象的存在。ui
用來修飾與語句塊-稱之爲靜態代碼塊。先於構造方法以前執行,只會執行一次。用來對靜態成員作初始化this
靜態修飾的成員被全部的對象共享spa
調用的時候能夠直接經過類名.成員來進行訪問。code
static關鍵字注意事項視頻
1.靜態方法中只能訪問外部的靜態成員 (爲何?當咱們去調用靜態方法的時候,對象都沒產生,對象沒產生怎麼可能有屬性呢,由於屬性是屬於某個對象的對吧) 2.靜態方法中不能出現this關鍵字 (爲何?一樣的道理,當咱們去調用靜態方法的時候,對象都沒產生,對象沒產生this又是指誰呢?)對象
ok 上代碼!生命週期
public class StaticDemo {
public static void main(String[] args)
{
Device device1 = new Device();
device1.showName();
device1.showEnergy();
Device device2 = new Device();
device2.energy++;
device2.showName();
device2.showEnergy();
}
}
class Device
{
private String name="device1";//普通的屬性
public int energy=2;//普通的屬性
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getEnergy() {
return energy;
}
public void setEnergy(int energy) {
this.energy = energy;
}
public void showName()
{
System.out.println(name);
}
public void showEnergy()
{
System.out.println(energy);
}
}
複製代碼
看下輸出結果:內存
device1
2
device1
3
複製代碼
ok,如今分析下,我第一個對象的energy
屬性初始值時2
,第二個對象的energy
屬性我用public
修飾了,因此我直接能夠調用下,而後加一
了,打印出來的結果兩個對象是不同的。這就說明了什麼?每一個對象都有他本身的獨立的一份屬性。對不對?~對的哈。。這句話很重要~~
那我如今若是把name
這個屬性改爲用static
來修飾的話,如今會怎麼樣? public static String name="device1";//靜態變量,他如今不屬於任何一個對象了,被多個對象共享,他如今是屬於類的,他也稱爲類變量
如今咱們把調用方法改爲這樣
public static void main(String[] args)
{
Device device1 = new Device();
device1.name = "cyy";
device1.showName();
device1.showEnergy();
Device device2 = new Device();
device2.energy++;
device2.showName();
device2.showEnergy();
}
複製代碼
如今name
不是個屬性了,他如今是個靜態變量,我在device1
裏面把他設置成cyy
,如今打印結果來看下。
cyy
2
cyy
3
複製代碼
看到沒兩個name
都變成cyy
了。這說明了什麼?這是否是說明了,這個name
你們都共享了呀,再也不是每一個對象獨立擁有的了,對吧! 那既然他都不是共享的了,那咱們訪問的時候是否是就能夠直接Device.name
就能夠了啊,由於他如今不屬於對象了,他如今屬於類的。 而age
可不能夠直接經過Device.age
來訪問啊,固然不能夠,由於他如今並不屬於類對吧。
好的,如今若是咱們把一個方法改爲靜態的呢,好比這樣:
public static void showName()
{
System.out.println(energy);
System.out.println(name);
}
複製代碼
若是這麼寫的話,是否是會報錯呀,編譯時就會報錯,會提示: Non-static field 'energy' cannot be referenced from a static context
什麼意思?大概意思就是說,你靜態方法不能訪問非靜態變量~爲何?!由於你靜態方法調用的時候,尚未建立對象呢,人家energy
是個屬性,又不是靜態變量,你會跑的時候,人家還沒出生呢,你咋能去找人家玩兒呢?對吧,因此靜態方法不能訪問非靜態變量
,靜態方法中不能使用this
,只能訪問外部靜態的東西。
那非靜態方法
可不能夠訪問靜態變量
?思考一下?答案固然是能夠的,想像一下,靜態變量在你對象建立以前就已經分配好內存空間了,已經存在了,你對象建立完以後,他已經存在了,因此確定是能夠訪問的,對吧。總結就是靜態的只能訪問靜態的,非靜態的均可以訪問
。
還有個static語句塊
他何時執行呢?
在類被加載的時候就會執行,只會執行一次,用來對靜態變量進行初始化。優先於構造方法
的執行。
上代碼:
class Device
{
public static String name;//普通的屬性
public int energy=2;//普通的屬性
//static語句塊
static {
name = "device1";
System.out.println("===我是靜態語句塊裏的"+name);
}
//構造方法
public Device(String name)
{
this.name = name;
System.out.println("===我是構造方法裏的"+name);
}
public static void showName()
{
System.out.println(name);
}
public void showEnergy()
{
System.out.println(energy);
}
}
複製代碼
咱們如今使用下:
Device device1 = new Device("cyy");
Device device2 = new Device("cyy513");
複製代碼
看下打印結果:
===我是靜態語句塊裏的device1
===我是構造方法裏的cyy
===我是構造方法裏的cyy513
複製代碼
發現了吧,我new
了兩個對象,可是靜態語句塊裏的system.out.println
只打印了一次,說明啥static語句塊只執行一次,無論你建立多少次對象。
並且我是先於構造方法執行的。
那會有人說,那我之後都不用屬性了,我所有用static變量,多好,多方便,其實這樣有不少缺點:
那咱們何時用static呀?
當咱們一個類裏面,沒有任何屬性,只有方法 ,而這個方法是爲其餘的類服務的,這個時候適合用static的。
定義:
顧名思義,單例模式的意思就是隻有一個實例,單例模式確保某一個類只有一個實例,並且自行實例化併爲整個系統提供這個實例,這個類稱爲單例類。
通俗的說,就是我有一個類,整個系統就一個實例,並且他是本身建立本身,他必須對外提供個方法,把我本身給你。
上代碼:
class SingleTon
{
private SingleTon singleTon = new SingleTon();
/**
* 構造方法必定不能是公開的,否則別人就能夠隨便構造了。
* 因此構造方法必須是private,對吧
*/
private SingleTon()
{
}
//若是我這麼寫,會出現什麼問題
public static SingleTon getInstance()
{
return singleTon;
}
}
複製代碼
是否是會出現以前說的那種錯誤呀,靜態方法不能引用非靜態變量
。對不對。因此要怎麼作?是否是給前面singleton
加上個static
就能夠了是吧。由於這個SingleTon是靜態的在內存裏只有一份對吧~正確寫法,
class SingleTon
{
public static SingleTon singleTon = new SingleTon();
private SingleTon()
{}
public static SingleTon getInstance()
{
return singleTon;
}
}
複製代碼
這種方式稱之爲餓漢式
。爲何?由於我在調用getInstance()
以前這個對象是否是就已經產生了呀,由於它是靜態的嘛,在類加載時候,就已經new SingleTon()
了呀。那咱們如今有沒有更好的方法呢? 好比在getInstance()
的時候再去建立這個對象呀?固然能夠呀~這麼寫就能夠了.
class SingleTon
{
public static SingleTon singleTon = null;
/**
* 構造方法必定不能是公開的,否則別人就能夠隨便構造了。
* 因此構造方法必須是private,對吧
*/
private SingleTon()
{
}
//若是我這麼寫,會出現什麼問題
public static SingleTon getInstance()
{
if (singleTon==null)
{
singleTon = new SingleTon();
}
return singleTon;
}
}
複製代碼
這種就是懶漢式
加載。
不論是懶漢式
仍是餓漢式
,是否是目的就是一個,讓他整個系統中只有一個實例。
ok,結束~ 後續我會繼續更新,Android自定義View,Android NDK,音視頻方向的文章,歡迎你們關注,共同進步。