爲什麼不允許使用 Java 靜態構造函數?

不允許使用 Java 靜態構造函數,但是爲什麼呢?在深入探討不允許使用靜態構造函數的原因之前,讓我們看看如果要使 構造函數靜態化 會發生什麼。

Java 靜態構造函數

假設我們有一個定義爲的類:

public class Data {

	private int id;
	
	public static Data() {}
}

如果您嘗試編譯此類,則會在 Data 類型的構造函數中收到一條錯誤消息,作爲**非法修飾符。**僅允許公開,受保護和私有

在這裏插入圖片描述

靜態屬於類,構造函數屬於對象

我們知道靜態方法,靜態塊或變量屬於該類。而構造函數屬於該對象,並在使用 new 運算符創建實例時調用。由於構造函數不是類屬性,因此有理由認爲它不能是靜態的。

靜態塊 / 方法無法訪問非靜態變量

我們知道靜態方法不能訪問非靜態變量。靜態塊也是如此。

現在,構造函數的主要目的是初始化對象變量。因此,如果我們將構造函數設置爲靜態,則無法初始化對象變量。這將破壞使用創建對象的構造函數的全部目的。因此,使構造函數爲非靜態是合理的。

注意,我們不能this在靜態方法中使用引用對象變量。下面的代碼將定義編譯錯誤,因爲:不能在靜態上方中使用它

public static void main(String args []){
	System.out.println(this.id);
}

在這裏插入圖片描述

靜態構造函數將破壞繼承

在Java中,每個類都隱式擴展了對象類。我們可以定義一個類層次結構,其中子類構造函數調用超類構造函數。這是通過super()方法調用完成的。大多數情況下,JVM自動調用超類構造函數,但有時如果超類中有多個構造函數,我們必須手動調用它們。

讓我們來看一個super()用法示例。


package com.journaldev.util;

class Data {
	Data() {
		System.out.println("Data Constructor");
	}
}

public class DataChild extends Data{
	public DataChild() {
		super(); //JRE calls it explicitly, calling here for explanation
		System.out.println("DataChild Constructor");
	}
	
	public static void main(String args[]) {
		DataChild dc = new DataChild();
	}
}

上面的程序將產生以下輸出。


Data Constructor
DataChild Constructor

如果,您看一下super()方法,它不是靜態的。因此,如果構造函數轉換靜態,我們將無法使用它,這將破壞java中的繼承性。

### Java靜態構造方法替代

如果要在類中初始化一些靜態變量,則可以使用靜態塊。請注意,我們無法將參數傳遞給靜態塊,因此,如果您要初始化靜態變量,則也可以在常規構造函數中執行此操作。


class Data {
	public static int count;
	
	static {
		count = 0;
	}
	Data(int c) {
		//not recommended since the count is class variable 
		//and shared among all the objects of the class
		count=c; 
	}
}


總結

我們說明了爲什麼不允許使用Java靜態構造函數。我們可以使用靜態塊以及構造函數本身來初始化靜態變量。


“不積跬步,無以至千里”,希望未來的你能:有夢爲馬 隨處可棲!加油,少年!

關注公衆號:「Java 知己」,每天更新Java知識哦,期待你的到來!

  • 發送「Group」,與 10 萬程序員一起進步。
  • 發送「面試」,領取BATJ面試資料、面試視頻攻略。
  • 發送「玩轉算法」,領取《玩轉算法》系列視頻教程。
  • 千萬不要發送「1024」…

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章