一个糟糕的实践在构造函数上使用init()方法吗?

时间:2017-08-28 20:12:55

标签: java constructor initialization

这些天我在java上阅读良好的实践,并且在某些时候  我的世界已碎裂,因为他们说调用“init”方法  构造函数可能是一个糟糕的实践,我知道..公共方法可以被覆盖,  但在我的情况下有点不同,所以请帮我们理解。例如:

    public class MLabel extends JLabel {

    private Color color;

    public MLabel(String txt, Color color, int align) {
        super(txt, null, align);
        this.color = color;
        init(); 
    }

    private void init() {
        setFont(new Font(Font.SERIF, Font.BOLD, 16));
        setForeground(color);
    }

}
  

我已经阅读了这个答案,但仍然找不到解决方案,认为工厂会为这个简单的任务制作一个强大的代码,我只想“配置”JLabel以方便使用

     

谢谢大家,关于编程的良好实践的研究有点难,因为问题不会出现错误但是如何制作,我已经为所有答案提出了好的建议,我会改变这些问题()现在工厂,至少...谢谢

3 个答案:

答案 0 :(得分:0)

  

构造函数不得直接或间接调用可覆盖的方法。如果违反此规则,将导致程序失败。超类构造函数在子类构造函数之前运行,因此在子类构造函数运行之前将调用子类中的重写方法。如果重写方法依赖于子类构造函数执行的任何初始化,则该方法将不会按预期运行。为了使这个具体,这是一个违反这条规则的类:

来源: Effective Java,Second Edition ,第89页。

您可以阅读整个讨论,以了解为什么不在构造函数中调用init方法。使用生命周期钩子是个好主意,例如像spring这样的框架提供了这样的功能。

答案 1 :(得分:0)

最好通过简单的字段初始化来简化构造函数,并在另一个专门用于此目的的 Factory 类中分离复杂的初始化,如init()。

答案 2 :(得分:0)

在java中使用“精益 - 构造函数”是一种很好的做法。特别是像春天这样的框架。在构造函数中,如果有一个init,很有可能它被用来误用它。让我们说通过init连接到数据库。这是一个潜在的失败点。避免这种情况是一种很好的做法。最好能够首先创建bean或对象,然后在第一次使用对象时失败,如果配置错误或初始化。

在您的情况下,如果创建对象Font失败怎么办?在这种情况下,你甚至没有创建MLabel。最好避免这种情况。