我应该使用包含构造函数中的其他逻辑的setter吗?

时间:2016-10-07 06:43:21

标签: java

我有一个类,只要设置了新列表,就需要在列表中重置其内部迭代器:

public class ListElementReceiver implements ElementReceiver {
    private List<Element> elements;
    private Iterator<Element> elementIter;

    public void reset() {
        elementIter = elements.iterator();
    }

    public void setElements(List<Element> elements) {
        this.elements = elements;
        reset();
    }
}

它基本上只是一个列表及其迭代器的包装器,因此我可以将它与我给定的接口ElementReceiver一起使用。我遇到的问题是为这个类构建构造函数。哪两种方法更可取?

// Approach 1: Duplicate logic, independant of Setter
public ListElementReceiver() {
    elements = new List<Element>();
    reset();
}

public ListElementReceiver(List<Element> elements) {
    this.elements = elements;
    reset();
}

//Approach 2: Make dependant on Setter
public ListElementReceiver() {
    setElements(new List<Element>());
}

public ListElementReceiver(List<Element> elements) {
    setElements(elements);
}

1 个答案:

答案 0 :(得分:5)

从构造函数中,您不应该调用可以被子类覆盖的方法(包括setter)。这可能导致子类中的代码在子类完全构造之前执行,这可能导致难以跟踪的错误。

可以调用privatefinal方法(前提是它们不会调用任何可重写的代码),或调用final类中的方法,但是看起来不像你在这里。

通过让一个构造函数调用另一个构造函数,您可以避免使用第一种方法重复逻辑:

public ListElementReceiver() {
    this(new ArrayList<>());
}

public ListElementReceiver(List<Element> elements) {
    this.elements = elements;
    elementIter = elements.iterator();
}