1. 程式人生 > >[每日一問]---“static”關鍵字是什麼意思?Java中可以重寫一個static方法嗎?

[每日一問]---“static”關鍵字是什麼意思?Java中可以重寫一個static方法嗎?

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成員
  • 不能訪問外部類的非靜態成員