值得思考的关于对象的一段代码
private int i = giveMeJ();
private int j = 20;
private int giveMeJ() {
return j;
}
public static void main(String[] args) {
System.out.println("i: " + new InvalidValue().i);
}
第一次看到这个,属实有些懵逼,第一感觉private声明的属性可以直接赋值?Google了一圈看到了关于这段代码的分析:
Java keeps the default constructor if no constructor is present, Hence let us keep the default constructor in the code to understand the code flow and value of i and j at each step
如果没有构造函数,就保持默认的构造函数
Follow this:
public class InvalidValue {
private int i = giveMeJ();
private int j = 20;
// Default Constructor
public InvalidValue() {
super();
// Second Print: inside Constructor[i= 0, j= 20]
System.out.println("inside Constructor[i= " + i + ", j= " + j + "]");
}
private int giveMeJ() {
// First Print: inside giveMeJ[i= 0, j= 0]
System.out.println("inside giveMeJ[i= " + i + ", j= " + j + "]");
return j;
}
public static void main(String[] args) {
// Third Print: i: 0
System.out.println("i: " + new InvalidValue().i);
}
将代码稍微修改加上System.out.println()语句更方便的查看代码的执行顺序:
- Step 1: void main initiate the call by new InvalidValue().i,
- Step 2: i and j will be initiated by default value 0 then InvalidValue() constructor will be invoked and then super(); will be called,
- Step 3: Now the constructor (assign value to instance attributes) invokes private int i = giveMeJ(),
4.Step 4: giveMeJ() method will be invoked and here value of i is 0 also value of j is 0, hence this method will return 0, - step 5: i initialize by 0, now flow will go to private int j = 20,
- step 6: 20 value will be assigned to j,
- step 7: now the compiler will return to constructor (Step 3) and then it will print sysout statement (inside Constructor[i= 0, j= 20]),
- step 8: now compiler will return to void main() (Step 1) and it will print sysout statement (i: 0)
最终输出结果:
inside giveMeJ[i= 0, j= 0]
inside Constructor[i= 0, j= 20]
i: 0