复制构造函数访问其 class 的字段?
copy constructor accessing fields of its class?
我正在阅读 mutable/immutable 类 和 java 中的复制构造函数,偶然发现了 this example。
在复制构造函数中,他使用如下 getter:
/**
* Copy constructor.
*/
public Galaxy(Galaxy aGalaxy) {
this(aGalaxy.getMass(), aGalaxy.getName());
//no defensive copies are created here, since
//there are no mutable object fields (String is immutable)
}
我的问题是,对于某些人来说,在复制构造函数中使用 getter 而不是仅仅访问字段,例如 (aGalaxy.aMass, aGalaxy.aName)
,除了这是一种良好的编码习惯之外,还有其他原因吗?你也可以找到这样做的例子,但我的意思是它纯粹是一种编码风格,还是在复制构造函数中使用 getters 有潜在的好处?
虽然在大多数情况下无害,但当子类选择覆盖您调用的 getter 时,这种做法可能会导致一些难以捕捉的错误。
这是一个简单的例子:
class Base {
private final String name;
public String getName() {return name;}
public Base(String name) {
this.name = name;
}
public Base(Base b) {
this(b.getName());
}
}
class Derived extends Base {
public String getName() {
return "["+super.getName()+"]";
}
public Derived(String name) {
super(name);
}
public Derived(Derived d) {
this(d.getName());
}
}
请注意 Derived
如何覆盖 getName()
,因此 Derived
的复制构造函数正在访问名称的修改版本,从而导致问题:
Derived orig = new Derived("hello");
Derived copy = new Derived(orig);
System.out.println(orig.getName()); // Prints [hello]
System.out.println(copy.getName()); // Prints [[hello]]
最后一张印刷品的方括号加倍,所以副本不是真正的副本。
使用 protected
变量或使你的 getters final
可以帮助你避免这个问题。
我认为这个问题的根本原因是让子类覆盖存储属性的 getter,所以我更喜欢让你的 getter final
.
的方法
我正在阅读 mutable/immutable 类 和 java 中的复制构造函数,偶然发现了 this example。
在复制构造函数中,他使用如下 getter:
/**
* Copy constructor.
*/
public Galaxy(Galaxy aGalaxy) {
this(aGalaxy.getMass(), aGalaxy.getName());
//no defensive copies are created here, since
//there are no mutable object fields (String is immutable)
}
我的问题是,对于某些人来说,在复制构造函数中使用 getter 而不是仅仅访问字段,例如 (aGalaxy.aMass, aGalaxy.aName)
,除了这是一种良好的编码习惯之外,还有其他原因吗?你也可以找到这样做的例子,但我的意思是它纯粹是一种编码风格,还是在复制构造函数中使用 getters 有潜在的好处?
虽然在大多数情况下无害,但当子类选择覆盖您调用的 getter 时,这种做法可能会导致一些难以捕捉的错误。
这是一个简单的例子:
class Base {
private final String name;
public String getName() {return name;}
public Base(String name) {
this.name = name;
}
public Base(Base b) {
this(b.getName());
}
}
class Derived extends Base {
public String getName() {
return "["+super.getName()+"]";
}
public Derived(String name) {
super(name);
}
public Derived(Derived d) {
this(d.getName());
}
}
请注意 Derived
如何覆盖 getName()
,因此 Derived
的复制构造函数正在访问名称的修改版本,从而导致问题:
Derived orig = new Derived("hello");
Derived copy = new Derived(orig);
System.out.println(orig.getName()); // Prints [hello]
System.out.println(copy.getName()); // Prints [[hello]]
最后一张印刷品的方括号加倍,所以副本不是真正的副本。
使用 protected
变量或使你的 getters final
可以帮助你避免这个问题。
我认为这个问题的根本原因是让子类覆盖存储属性的 getter,所以我更喜欢让你的 getter final
.