为什么不允许使用Java静态构造函数?

时间:2020-02-23 14:34:31  来源:igfitidea点击:

不允许使用Java静态构造函数,但是为什么呢?在深入探讨不允许使用静态构造函数的原因之前,让我们先看看如果要将静态构造函数设为静态会发生什么。

Java静态构造函数

假设我们有一个定义为的类:

public class Data {

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

如果您尝试编译此类,则会在Data类型的构造函数中收到一条错误消息,作为非法修饰符。
仅允许公开,受保护和私有。

为什么不允许使用静态构造函数?

让我们来看看一些引人入胜的理由,原因是不允许在Java中使用静态构造函数。

静态属于类,构造函数属于对象

我们知道静态方法,块或者变量属于该类。
而构造函数属于该对象,并在使用new运算符创建实例时调用。
由于构造函数不是类属性,因此有理由认为它不能是静态的。

静态块/方法无法访问非静态变量

我们知道静态方法无法访问非静态变量。
静态块也是如此。

现在,构造函数的主要目的是初始化对象变量。
因此,如果我们将构造函数设为静态,则它将无法初始化对象变量。
这将使拥有用于创建对象的构造函数的全部目的无效。
因此,使构造函数为非静态是合理的。

请注意,我们不能在静态方法中使用this来引用对象变量。
下面的代码将给出编译错误,因为:不能在静态上下文中使用它。

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

静态构造函数将破坏继承

在Java中,每个类都隐式扩展Object类。
我们可以定义一个类层次结构,其中子类构造函数调用超类构造函数。
这是通过调用super()方法完成的。
大多数情况下,JVM自动调用超类构造函数,但有时如果超类中有多个构造函数,我们必须手动调用它们。

我们来看一个使用" super()"的示例。

package com.theitroad.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静态构造方法替代

如果要在类中初始化一些静态变量,则可以使用静态块。
请注意,我们无法将参数传递给static块,因此,如果您要初始化静态变量,则也可以在常规构造函数中执行此操作。

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; 
	}
}