public class DataStoreAccess {
private final int CAPACITY = 9; //数组的默认容量
protected int capacity; //数组的实际容量
private Film[] arrayFilm;
private Person[] arrayPerson;
private Order[] arrayOrder;
/**
* 数据存储类构造函数(单例模式)
*/
private DataStoreAccess(){
this(CAPACITY);//报错!!!!!!!!!
}
/**
* 构造函数的重载
* @param length
*/
private DataStoreAccess(int length){
capacity = length;
arrayFilm = new Film[capacity];
arrayPerson = new Person[capacity];
arrayOrder = new Order[capacity];
}
}
private final int CAPACITY = 9; //数组的默认容量
protected int capacity; //数组的实际容量
private Film[] arrayFilm;
private Person[] arrayPerson;
private Order[] arrayOrder;
/**
* 数据存储类构造函数(单例模式)
*/
private DataStoreAccess(){
this(CAPACITY);//报错!!!!!!!!!
}
/**
* 构造函数的重载
* @param length
*/
private DataStoreAccess(int length){
capacity = length;
arrayFilm = new Film[capacity];
arrayPerson = new Person[capacity];
arrayOrder = new Order[capacity];
}
}
private final static int CAPACITY = 9;
this(DataStoreAccess.CAPACITY);改这两句
Cannot refer to an instance field CAPACITY while explicitly invoking a constructor如果在里面随便写入一个数字,就没错
这解释的是lz这情况么哪有child's constructor 和its parent Constructor。。一直以来自己理解的初始化顺序又要改变了。。
如果是静态,那么可以通过类获取
大概这么解释如果把this(9);
因为9是常量
9是final static int
你无论静态或者非静态方法,你都可以访问这个9你想象一下构造方法正在构造的时候要获取构造后对象里的成员对象
是不是有点矛盾?
Cannot refer to an instance field CAPACITY while explicitly invoking a constructor
我是这么理解的:初始化顺序仍然是先完成了 private final int CAPACITY = 9; 然后才调用 构造函数 的。
这个并没有任何改变。但是如果考虑另外一个约束就不同了,Java要求在父类完成构造之前,是不能访问子类任何成员的。实际上在父类的构造函数完成之前,子类的成员根本就不会开始被执行。在这种情况下,this(CAPACITY);这句话被编译时,其父类还未完成构造,所以不能引用子类的成员。另外要注意的就是,所有类至少有都有Object父类,所以不能说这个类没有父类啊。我为了测试相关场景,做了个有点复杂的例子:public class TestConstructor {
private final int a = get(1);
private final int b = count(a);
private final NoneXX none = new NoneXX(b); static {
System.out.println("STATIC TestConstructor");
}
public TestConstructor() {
this(0);
System.out.println("Constructor TestConstructor()");
} public TestConstructor(int in) {
System.out.println("Constructor TestConstructor(" + in + ")");
} public int get(int tmp) {
System.out.println("get(" + tmp + ")");
return tmp;
} public int count(int tmp) {
tmp = tmp * 10 + tmp;
System.out.println("count(" + tmp + ")");
return tmp;
} public static void main(String[] args) {
new SubTest();
}}class SubTest extends TestConstructor {
private final int a = get(2);
private final int b = count(a);
private final NoneYY none = new NoneYY(b);
static {
System.out.println("STATIC SubTest");
}
public SubTest() {
this(0);
System.out.println("Constructor SubTest()");
} public SubTest(int in) {
super(in);
System.out.println("Constructor SubTest(" + in + ")");
}
}class NoneXX {
static {
System.out.println("STATIC NoneXX");
}
public NoneXX(int in) {
System.out.println("Constructor NoneXX(" + in + ")");
}
}class NoneYY {
static {
System.out.println("STATIC NoneYY");
}
public NoneYY(int in) {
System.out.println("Constructor NoneYY(" + in + ")");
}
}
输出结果是:
STATIC TestConstructor // 父类的静态块
STATIC SubTest //子类的静态块
get(1) // 父类的成员变量初始化
count(11) // 父类的成员变量初始化
STATIC NoneXX // 父类的成员变量初始化时引发NoneXX的静态块
Constructor NoneXX(11) // 同上,NoneXX构造函数
Constructor TestConstructor(0) // 父类构造函数被调用,这里比较奇特,实际上注意到它应该是经过子类 this(0)->super(0)->TestConstructor(0),然而此时子类啥都没被初始化;所以注意到子类的参数0,当然不能引用子类的任何成员变量。
get(2)
count(22)
STATIC NoneYY
Constructor NoneYY(22)
Constructor SubTest(0)
Constructor SubTest()
也是第一次关注这么细节,确实有意思。
至于其背后的深层次的原理,还没想到。