这个问题可能很愚蠢,但我只是想知道,有什么不同吗?
class A{
// common code
private int field;
public void setField(int field){
this.field = field;
}
//way 1
public A(int field){
this.field = field;
}
//way 2
public A(int field){
setField(field);
}
}
答案 0 :(得分:4)
我怀疑没有“更好”的方式,只是想在当时适合你的目的。
我很喜欢 Way#1 。这是因为我尝试尽可能地将代码设为Encapsulated。在某种程度上,它也可以被认为是编程Java的Functional方式,因为您正在减少副作用。有时一起消除它们。
class A{
// common code
private int field;
public void setField(int field){
this.field = field;
}
//way 1
public A(int field){
this.field = field;
}
}
可以改写为......
class A{
// common code
private final int field;
//way 1
public A(int field){
this.field = field;
}
是的,如果您需要在实例化后更改 field 的值,它将无效。也可以是 field 另一个对象或集合。
但是为了使课程尽可能不可变,可以标记为私有最终的字段也是如此。
当然,你不能用setter方法做到这一点。
答案 1 :(得分:2)
方式2更好,因为它为您提供了设置变量值的统一方法。但它带来了风险,因为你在构造函数中调用了一个可重写的方法。所以正确的语法是使用final关键字:
public final void setField(int field){
this.field = field;
}
//way 2
public A(int field){
setField(field);
}
使用final
时,不会覆盖该方法。如果您无法承担最终方法,请不要在构造函数中调用setter。但是覆盖一个setter通常很奇怪。
这很好,因为您可能希望稍后更改设置器:
IllegalArgumentException
。你必须在一个地方做到这一点。这是DRY principle.
的实现public final synchronized void setField(int field){
if (0 <= field && field <= MAX_VALUE) {
this.field = field;
} else {
throw new IllegalArgumentException();
}
}
//still has all the benefits of setter
public A(int field){
setField(field);
}
A = new A(-1) //throws IllegalArgumentException
不要担心额外方法调用的优化和费用。 JVM通常可以通过内联方法来优化这些代码。
真正让开发变得更慢的是搜索错误。此方法可帮助您减少错误并更轻松地维护代码。
答案 2 :(得分:0)
嗯,对我而言,一方面是更多Java。我的意思是,我们应该知道构造函数应该做什么(在初始化时设置实例属性)以及setter应该做什么(提供一个公开的开放点来在你想要的时候更改实例属性)。
我们不应该在构造函数中放置任何逻辑
只是我的选择。