java static 精準解讀
工作中主要是:方便在沒有創建對象的情況下來進行調用(方法/變量),通過類名直接調用靜態的方法和變量。
java教程的解釋:static方法就是沒有this的方法。在static方法內部不能調用非靜態方法,但反過來是可以的。
1.雖然對於靜態方法來說沒有this,那麼在非靜態方法中能夠通過this訪問靜態成員變量嗎?先看下面的一個例子,這段代碼輸出的結果是什麼?
public class Main
{
static int value
= 33;
public static void main(String[]
args) throws Exception{
new Main().printValue();
}
private void printValue(){
int value
= 3;
System.out.println(this.value);
}
}
這裏面主要考察隊this和static的理解。this代表什麼?this代表當前對象,那麼通過new Main()來調用printValue的話,當前對象就是通過new Main()生成的對象。而static變量是被對象所享有的,因此在printValue中的this.value的值毫無疑問是33。在printValue方法內部的value是局部變量,根本不可能與this關聯,所以輸出結果是33。在這裏永遠要記住一點:靜態成員變量雖然獨立於對象,但是不代表不可以通過對象去訪問,所有的靜態方法和靜態變量都可以通過對象訪問(只要訪問權限足夠)。
2.這段代碼的輸出結果是什麼?
public class Test extends Base{
static{
System.out.println("test
static");
}
public Test(){
System.out.println("test
constructor");
}
public static void main(String[]
args) {
new Test();
}
}
class Base{
static{
System.out.println("base
static");
}
public Base(){
System.out.println("base
constructor");
}
}
結果:
base static
test static
base constructor
test constructor
至於爲什麼是這個結果,我們先不討論,先來想一下這段代碼具體的執行過程,在執行開始,先要尋找到main方法,因爲main方法是程序的入口,但是在執行main方法之前,必須先加載Test類,而在加載Test類的時候發現Test類繼承自Base類,因此會轉去先加載Base類,在加載Base類的時候,發現有static塊,便執行了static塊。在Base類加載完成之後,便繼續加載Test類,然後發現Test類中也有static塊,便執行static塊。在加載完所需的類之後,便開始執行main方法。在main方法中執行new
Test()的時候會先調用父類的構造器,然後再調用自身的構造器。因此,便出現了上面的輸出結果。
3.這段代碼的輸出結果是什麼?
public class Test
{
Person
person = new Person("Test");
static{
System.out.println("test
static");
}
public Test()
{
System.out.println("test
constructor");
}
public static void main(String[]
args) {
new MyClass();
}
}
class Person{
static{
System.out.println("person
static");
}
public Person(String
str) {
System.out.println("person
"+str);
}
}
class MyClass extends Test
{
Person
person = new Person("MyClass");
static{
System.out.println("myclass
static");
}
public MyClass()
{
System.out.println("myclass
constructor");
}
}
結果:
test static
myclass static
person static
person Test
test constructor
person MyClass
myclass constructor
類似地,我們還是來想一下這段代碼的具體執行過程。首先加載Test類,因此會執行Test類中的static塊。接着執行new MyClass(),而MyClass類還沒有被加載,因此需要加載MyClass類。在加載MyClass類的時候,發現MyClass類繼承自Test類,但是由於Test類已經被加載了,所以只需要加載MyClass類,那麼就會執行MyClass類的中的static塊。在加載完之後,就通過構造器來生成對象。而在生成對象的時候,必須先初始化父類的成員變量,因此會執行Test中的Person
person = new Person(),而Person類還沒有被加載過,因此會先加載Person類並執行Person類中的static塊,接着執行父類的構造器,完成了父類的初始化,然後就來初始化自身了,因此會接着執行MyClass中的Person person = new Person(),最後執行MyClass的構造器。
4.這段代碼的輸出結果是什麼?
public class Test
{
static{
System.out.println("test
static 1");
}
public static void main(String[]
args) {
}
static{
System.out.println("test
static 2");
}
}
結果:
test static 1
test static 2
雖然在main方法中沒有任何語句,但是還是會輸出,原因上面已經講述過了。另外,static塊可以出現類中的任何地方(只要不是方法內部,記住,任何方法內部都不行),並且執行是按照static塊的順序執行的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.