Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-在默认构造函数之前执行的方法_Java_Constructor - Fatal编程技术网

Java-在默认构造函数之前执行的方法

Java-在默认构造函数之前执行的方法,java,constructor,Java,Constructor,我正在学习java,无意中遇到了以下代码,其中默认构造函数在方法之后执行 public class ChkCons { int var = getVal(); ChkCons() { System.out.println("I'm Default Constructor."); } public int getVal() { System.out.println("I'm in Method."); retur

我正在学习java,无意中遇到了以下代码,其中默认构造函数在方法之后执行

public class ChkCons { 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(); } } 公共类ChkCons{ int var=getVal(); ChkCons(){ System.out.println(“我是默认构造函数”); } 公共int getVal(){ System.out.println(“我在方法中”); 返回10; } 公共静态void main(字符串[]args){ ChkCons c=新的ChkCons(); } } 输出:

I'm in Method. I'm Default Constructor. 我有办法。 我是默认构造函数。 谁能解释一下为什么会发生这种事


谢谢。

实例变量初始化表达式,如
int var=getVal()在超级类构造函数执行之后,但在当前类构造函数的主体执行之前进行计算


因此,在执行
ChkCons
构造函数的主体之前调用
getVal()

这是因为您正在使用
int var=getVal()将方法初始化到字段中,因此它将在构造函数调用之前执行。

静态块具有第一优先级,它在类的加载过程中执行。

每当创建类的实例时,首先初始化实例变量,然后执行构造函数


Ref:

我们可以参考以下oracle文档来初始化实例变量(重点是我的):

初始化实例成员

通常,您会将初始化实例变量的代码放入 构造器除了使用构造函数 初始化实例变量:初始化程序块和最终方法。

实例变量的初始值设定项块看起来就像静态的 初始值设定项阻塞,但没有static关键字:

{ //初始化所需的任何代码都在这里}

>Java编译器将初始值设定项块复制到每个构造函数中。 因此,这种方法可用于在用户之间共享代码块 多个构造函数。

不能在子类中重写final方法。对此进行了讨论 在关于接口和继承的课程中。下面是一个例子 使用初始化实例变量的最终方法:

class Whatever {
private varType myVar = initializeInstanceVariable();

protected final varType initializeInstanceVariable() {

    // initialization code goes here
} 
}

将具有以下输出:

Static Block one
Static Block two
Init one
Init Two
Default Constructor
Init one
Init Two
Default Constructor
首先加载所有静态内容,然后加载实例内容。静态内容只加载一次

即使创建了两个对象,也只有在创建第一个对象时才会调用静态块

另外,在创建对象时或在构造函数中,如果您想使用这样的方法

 int var = getVal();

您应该使用静态方法。

构造函数在方法之前被调用。方法的执行发生在对象创建的一部分之后,在对象创建过程中,实例变量被计算。从下面的代码中可以更好地理解这一点

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();

    }

}
上述代码具有以下输出

Super constructor
I'm in Method.
I'm Default Constructor.

在这里,编译器自动添加
super()
作为
ChkCons()
构造函数中的第一条语句,因此它在
getVal()
方法之前被调用。

字段在调用构造函数之前被初始化,因为字段初始化调用
getVal
方法,它在构造函数之前被调用,然后是getVal()它会在静态块之前执行吗?构造函数?否,但是一个
静态
块(来自内存)将在FieldsRight之前执行一次,然后getVal()将在静态块之前执行吗?@RohitNigam否,在初始化类时执行静态初始值设定项块。这是在初始化该类的任何单个实例之前发生的。@RohitNigam它怎么可能发生呢?它需要一个实例。静态块中没有实例。“想一想吧!”霍尔格也许我的措辞不准确。我的意思是,实例变量初始化发生在当前类的构造函数的代码执行之前。我没有提到超类构造函数的代码何时执行。您应该将
getVal()
作为静态方法保留。
Super constructor
I'm in Method.
I'm Default Constructor.