[每日一問]---“static”關鍵字是什麼意思?Java中可以重寫一個static方法嗎?
阿新 • • 發佈:2019-01-24
1)static表示靜態的意思,表明一個被其修飾的成員變數(類成員)或者是成員方法(類方法)可以在沒有所屬類的例項變數的情況下被訪問。
2)Java中不可以重寫static方法,因為重寫Override是基於執行時動態繫結的,而static方法是編譯時靜態繫結的。static方法跟類的任何例項都不相關,所以不可以重寫static方法。
PS:Java中也不可以重寫一個private方法,因為private方法只能在當前類中被訪問,被private修飾的父類方法在子類中是不可見的。
關於Java中的static關鍵字
static 可以修飾:
- 變數(所謂 class variable)
- 方法(所謂 class method)
- 程式碼塊(所謂 block)
- 內部類(所謂 nested class)
凡是被 static 修飾的這四種元素,都屬於class的元素,即類的,而不是類的例項的。
1)靜態變數
- 靜態變數適合用在該變數被該類的所有例項所共享的時候。
- 靜態變數在類被載入的時候初始化,且僅分配一次記憶體。好處是記憶體利用率高。
class Student {
int id;
String name;
String school = "XiYou";
假設西安郵電大學有999999名學生,那麼每一個學生建立的時候,都會初始化學號、姓名、學校,那麼這些學生的學號、姓名各不相同,但是學校“XiYou”都是一樣的,如果每次都初始化一遍,就比較消耗記憶體。所以school是被該類的所有例項所共享的,因此可以將它宣告為static。
還有一個栗子:
Counter類中聲明瞭一個count變數,在建構函式中對其進行++操作,因為例項變數在物件被建立的時候分配記憶體,所以每一個物件都有一份自己count副本,每個物件各自count的++操作不會反應到其他物件上。
class Counter {
int count = 0;
Counter() {
count++;
System.out.println(count);
}
public static void main(String[] args) {
Counter c1 = new Counter();
Counter c2 = new COunter();
Counter c3 = new Counter();
}
}
Output:1
1
1
因為靜態變數僅僅在類載入的時候分配一次記憶體,所以如果將count修飾為static,那麼該類的所有物件都會共享該變數,每一個物件對count的操作都會反應到其他物件上。
class Counter2 {
static int count = 0;
Counter2() {
count++;
System.out.println(count);
}
public static void main(String[] args) {
Counter c1 = new Counter2();
Counter c2 = new COunter2();
Counter c3 = new Counter2();
}
}
Output:1
2
3
2)靜態方法
- 靜態方法屬於類而不是物件。
- 靜態方法可以直接通過類名呼叫,而不需要建立類的物件。
- 靜態方法可以修改靜態變數,而非靜態方法不可以。
一個靜態方法的栗子:
class Student2 {
int id;
String name;
static String school = "XiYou";
static void change() {
school = "XY";
}
Student2(int i, String n) {
id = i;
name = n;
}
void display() {
System.out.println(id + " " + name + " " + school);
}
public static void main(String[] args) {
Student2.change();
Student2 s1 = new Student2(4161074, "longer");
Student2 s2 = new Student2(4161075, "daner");
Student2 s3 = new Student2(4161076, "yaer");
s1.display();
s2.display();
s3.display();
}
}
第二個栗子:
public class Calculate {
static int cube(int x) {
return x*x*x;
}
public static void main(String[] args) {
int result = Calculate.cube(5);
System.out.println(result);
}
}
Output:125
靜態方法的兩個注意點:
- 靜態方法不能操作非靜態變數,也不能呼叫非靜態方法(可以這樣理解,靜態方法屬於類,直接通過類名就可以呼叫,而此時可能沒有任何例項,就談不上操作例項變數和呼叫例項方法了)。
- 靜態方法中不能使用this和super關鍵字。
比如這個栗子就是編譯錯誤的:
class A {
int a = 40;
public static void main(String[] args) {
System.out.println(a);
}
問題來了,那麼為什麼Java的main方法是static的?
答:為了使得在呼叫main方法之前不需要建立任何例項物件。
3)靜態程式碼塊
- 用來初始化靜態變數。
- 在類載入時,在執行main方法前執行相關操作。
栗子:
class A2 {
static {
System.out.println("static block is invoked");
}
public static void main(String[] args) {
System.out.println("Hello main");
}
Output:static block is invoked
Hello main
4)靜態內部類(被static修飾的類,並且處於某個類的內部)
- 可以訪問外部類的靜態成員,包括private成員
- 不能訪問外部類的非靜態成員