最近在接受Java Developer角色的采访时,我被问到如果它有一个成员变量,我是如何使A类不可变的,这是一个B类的对象,并且在一个B类在项目外部但不能的情况下由程序员编辑,而且B类甚至可能有自己的成员变量,这是另一个用户定义的类的对象。我给了它很多想法并且告诉面试官除非B级已经实施并且暴露了一种深度克隆自身的方法,否则没有办法。
面试官虽然不相信。有没有办法让这样的类不可变?
如果我能记得正确,那就是他解释的情况。他希望我让A级成为不可变的,那会是最好的答案吗?
final public class A {
final private B b;
A(B b) {
this.b = b; // Class b might/might not be cloneable
// this.b = (B)b.clone();
}
public B getB() {
return b;
// return (B)b.clone();
}
}
class B // external cannot edit
{
C c;
public C getC() {
return c;
}
public void setC(C c) {
this.c = c;
}
}
class C // external cannot edit
{
int i;
String j;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public String getJ() {
return j;
}
public void setJ(String j) {
this.j = j;
}
}
答案 0 :(得分:2)
不要向世界揭露B.所以没有一个返回B的方法。
而是识别B中的方法,它不会改变B并让A通过调用b中的相同方法来实现这些方法。
因此,如果B有方法calcSomething(),则应该有一个calcSomething()方法,它只返回b.calcSomething()。
答案 1 :(得分:0)
您可以使用以下内容:
final public class A {
final private B b;
A(B b) {
this.b = cloneB(b);
}
public B getB() {
return cloneB(b);
}
private static B cloneB(b){
B newB = new B();
C c = new C();
c.setI(b.getC().getI());
c.setJ(b.getC().getJ());
newB.setC(c);
return newB;
}
}
A类是100%不可变的情况。
更新:您还可以使用反射或分区来获取类的深层副本(如果类具有深层次结构),例如使用GSON进行分类:
private static B cloneB(b){
String tmp = new GSON().toJson(b);
return new GSON().fromJson(tmp, B.class);
}
左右