1.static是什麼
static在java中的意思是“靜态的”,什麼是靜态的?靜态的 意味着這個東西和對象無關,和類有關。
2.static作用在變量上
當static作用在變量上的時候,意味着這個變量被這個該類所有的對象共享(同一個hashCode位址),static表示的同一個hashCode,但不是表示該hash位址不可以改變,如果要該hash位址不改變,那是final的作用。看看如下代碼:
public class StaticTest {
private static String staticVar = "aaa";
public void changeStaticVar(){
staticVar = "bbb";
System.out.println(staticVar.hashCode());
}
public static void main(String[] args) {
System.out.println(StaticTest.staticVar.hashCode());
System.out.println("==============");
StaticTest test = new StaticTest();
test.changeStaticVar();
System.out.println(StaticTest.staticVar.hashCode());
}
}
//輸出結果
96321
==============
97314
97314
由此可以證明,當static修飾變量的時候,它更像是“屬于”類的,而不是屬于某一個對象的。
3.static作用于方法上
static作用于方法上,和作用于變量上的意義是大同小異的,它更像是“屬于”類的,而不是屬于某一個對象的。static方法在類執行個體化對象之前就已經存在。是以,在static方法中是不允許使用非static成員變量或方法的。為什麼?因為此時都沒有對象,怎麼使用對象的方法和變量?看看如下代碼:
public class StaticTest {
private String var = "aaa";
public static void changeStaticVar(){
//var = "bbb"; 編譯器報錯
}
}
思考:main方法也是用static修飾的,它有什麼特别之處?其實它的特别之處就是用了static,我以前在學習java的時候,總是想不new對象,直接在main方法裡使用該類的其它方法,卻永遠都是報錯,原來就是這個static在作怪。由此更可以看出,在main方法開始的時候,其實沒有任何對象被執行個體出來,是以就沒有辦法使用非static方法,除非執行個體化出對象。
那麼在反過來呢?在非static方法中能不能使用static變量?當然可以,非static的方法就是給對象調用的吧?對象已經生成了,static變量早已經生成了。
另外,其實類的構造器都是static的。
4.static靜态塊
static靜态塊在實際開發中非常有用,它在類加載的時候總是第一個被加載(僅次于靜态成員變量),看如下代碼
public class StaticTest {
private String var = getVar();
private static String staticVar = getStaticVar();
static{
System.out.println("static靜态塊");
}
public StaticTest() {
System.out.println("構造方法");
}
public String getVar(){
System.out.println("成員變量var");
return "var";
}
public static String getStaticVar(){
System.out.println("靜态成員變量staticVar");
return "staticVar";
}
public static void main(String[] args) {
StaticTest test = new StaticTest();
}
}
//輸出結果
靜态成員變量staticVar
static靜态塊
成員變量var
構造方法
其實從輸出結果就可以看出 static的特别:就是其獨立于對象之外。在對象還沒有生成的時候,它們就已經被執行個體化了。
思考:如果StaticTest類繼承了一個和它差不多類,那麼執行個體化對象時,是父類的靜态成員變量先執行個體化?還是子類先?大家可以自行實驗。
5.static作用于類
static不能作用于一般的類上,隻能作為某一個類的匿名類存在,雖然不知道有什麼意義:
public class StaticTest {
static class InnerClass{
}
public static void main(String[] args) {
InnerClass innerClass = new InnerClass();
}
}
6.一個小例子
思考下面這段代碼的輸出順序是什麼
//父類
public class FatherClass {
private String fs = finit();
private static String fs1 = fstaticInit();
private static String fstaticInit() {
System.out.println("父類靜态成員變量初始化!");
return "";
}
static {
System.out.println("父類靜态塊初始化!");
}
public FatherClass(){
System.out.println("父類構造函數初始化!");
}
private String finit(){
System.out.println("父類成員變量初始化!");
return "";
}
}
//子類
public class InitClass extends FatherClass{
private String s = init();
private static String s1 = staticInit();
private static String staticInit() {
System.out.println("子類靜态成員變量初始化!");
return "";
}
static {
System.out.println("子類靜态塊初始化!");
}
public InitClass(){
System.out.println("子類構造函數初始化!");
}
private String init(){
System.out.println("子類成員變量初始化!");
return "";
}
}
//main
public class Main {
public static void main(String[] args) {
InitClass initClass = new InitClass();
}
}
是不是非常好玩,自己體會,結果如下
1.父類靜态 成員變量初始化!
2.父類靜态塊初始化!
3.子類靜态成員變量初始化!
4.子類靜态塊初始化!
5.父類成員變量初始化!
6.父類構造函數初始化!
7.子類成員變量初始化!
8.子類構造函數初始化!
//序号是自己添加的
轉載于:https://my.oschina.net/u/3582320/blog/1503970