Java - Method executed prior to Default Constructor
我正在学习Java,偶然遇到了下面的代码,其中在方法之后执行默认构造函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
输出:
1 2 |
有人能解释一下为什么会这样吗?
谢谢。
实例变量初始化表达式(如
因此,在执行
在方法之前调用构造函数。方法的执行发生在对象创建过程中对实例变量进行计算的部分之后。从下面的代码可以更好地理解这一点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | class SuperClass{ SuperClass(){ System.out.println("Super constructor"); } } public class ChkCons extends SuperClass{ int var = getVal(); ChkCons() { System.out.println("I'm Default Constructor."); } public int getVal() { System.out.println("I'm in Method."); return 10; } public static void main(String[] args) { ChkCons c = new ChkCons(); } } |
以上代码输出如下
1 2 3 |
在这里,编译器自动添加
我们可以参考以下有关初始化实例变量的Oracle文档(重点是我的):
Initializing Instance Members
Normally, you would put code to initialize an instance variable in a
constructor. There are two alternatives to using a constructor to
initialize instance variables: initializer blocks and final methods.Initializer blocks for instance variables look just like static
initializer blocks, but without the static keyword:{
// whatever code is needed for initialization goes here }> The Java compiler copies initializer blocks into every constructor.
Therefore, this approach can be used to share a block of code between
multiple constructors.A final method cannot be overridden in a subclass. This is discussed
in the lesson on interfaces and inheritance. Here is an example of
using a final method for initializing an instance variable:
1
2
3
4
5
6
7
8 class Whatever {
private varType myVar = initializeInstanceVariable();
protected final varType initializeInstanceVariable() {
// initialization code goes here
}
}
https://docs.oracle.com/javase/tutorial/java/javaoo/initial.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | public class InitializerIndex { public InitializerIndex() { // TODO Auto-generated constructor stub System.out.println("Default Constructor"); } static { System.out.println("Static Block one"); } { System.out.println("Init one"); } void letsRoll() { } public static void main(String[] args) { new InitializerIndex().letsRoll(); new InitializerIndex().letsRoll(); } { System.out.println("Init Two"); } static { System.out.println("Static Block two"); } } |
将具有以下输出:
1 2 3 4 5 6 7 8 | Static Block one Static Block two Init one Init Two Default Constructor Init one Init Two Default Constructor |
首先加载所有静态内容,然后加载实例内容。静态内容只加载一次。
即使创建了两个对象,也只有在创建第一个对象时才调用静态块。
另外,在对象创建时或在构造函数中,如果要使用这样的方法
1 | int var = getVal(); |
您应该使用静态方法。
每当创建类实例时,首先初始化实例变量,然后执行构造函数
REF:在Java中运行构造函数代码之前,字段是否已初始化?
这是因为您正在使用