有两个类:A
和B
。 B
是A
的子类。 A
存储B
的引用,在某些情况下可能 对this
的引用。
public B b;
在A
的构造函数中,将this
引用转换为B
(提供,我知道对象的具体类型是否合法正在建设中B
)? (从语法上讲,我知道它是;在设计方面,它可能反映了一个糟糕的组件设计;但我想知道它是否有任何严重的风险,因此是不可接受的。)
public A(...parameters) {
b = (B) this;
}
问题出现了,因为到目前为止,B
的构造函数尚未完成(因为这恰好在B
调用super
时运行。)
我知道在构造函数完成之前访问b
意味着我正在访问(语义上)未初始化的成员(所以我从来没有这样做过),但这就是全部吗?
答案 0 :(得分:1)
- 如果其他类也延伸到A ,则会出现问题,然后默认情况下可以将其强制转换为B类。 /强>
- 我建议您使用instanceof
对此事进行排序....
答案 1 :(得分:1)
除了良好的OO设计之外,这个星座不会破坏任何其他规则。 Java已经为这种情况做好了准备,因为即使在调用任何构造函数之前,B的所有字段都会被初始化,如以下示例所示:
public class A {
int aMember;
public static final void main(String[] args) {
new B();
}
A() {
B b = (B) this;
System.out.println("in A(), before b.bMember has been set here, b.bMember = " + b.bMember);
System.out.println("in A(), before this.aMember has been set here, this.aMember = " + this.aMember);
this.aMember = 5;
b.bMember = 1; // will be overwritten in B()
System.out.println("in A(), after b.bMember has been set here, b.bMember = " + b.bMember);
System.out.println("in A(), after this.aMember has been set here, this.aMember = " + this.aMember);
}
}
-
public class B extends A {
int bMember;
B() {
super(); // invokes A()
System.out.println("in B(), before this.bMember has been set here, this.bMember = " + this.bMember);
this.bMember = 6;
System.out.println("in B(), after this.bMember has been set here, this.bMember = " + this.bMember);
}
}
输出:
in A(), before b.bMember has been set here, b.bMember = 0
in A(), before this.aMember has been set here, this.aMember = 0
in A(), after b.bMember has been set here, b.bMember = 1
in A(), after this.aMember has been set here, this.aMember = 5
in B(), before this.bMember has been set here, this.bMember = 1
in B(), after this.bMember has been set here, this.bMember = 6
这意味着在A()中,B的成员变量在设置之前与A的成员变量处于相同的状态。两者都已初始化为默认值(0表示int,false表示布尔值,null表示对象,...)并且可以使用。一个很大的缺陷是B的成员变量可以在A()中设置,但可以被B自己的构造函数覆盖,这非常违反直觉。
我喜欢这个问题,因为它表达得很简单明了,但它提出了更复杂的问题,这些问题涉及其他主题,如编译器内部和对象创建中的细节。