哪种设置字段值更好,为什么?

sas*_*ero 5 java optimization constructor

这个问题可能很愚蠢,但我只是想知道,有什么区别吗?

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Nic*_*kin 2

方式 2 更好,因为它为您提供了设置变量值的统一方式。但它带来了风险,因为您在构造函数中调用可重写的方法。所以正确的语法是使用final关键字:

public final void setField(int field){
     this.field = field;
}

//way 2
public A(int field){
    setField(field);
}
Run Code Online (Sandbox Code Playgroud)

final方法不会被覆盖。如果您无法承受最终方法,请不要在构造函数中调用 setter。但重写 setter 通常很奇怪。

这很好,因为您可能想稍后更改设置器:

  • 添加参数检查并在需要时抛出 an IllegalArgumentException
  • 添加计数器
  • 通知观察者(以 Observable 模式)
  • 使其成为同步块以提供线程安全
  • ...

而且您必须在一个地方完成此操作。这是DRY原则的一个实现

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
Run Code Online (Sandbox Code Playgroud)

不用担心额外方法调用的优化和开销。JVM通常可以通过内联方法来优化此类代码。

真正让开发变慢的是寻找错误。此方法可以帮助您减少错误并更轻松地维护代码。

  • 在构造函数中调用公共可重写方法可能存在安全风险 (2认同)