Java 在类中使用私有变量或公共方法,哪种做法更好?

Java 在类中使用私有变量或公共方法,哪种做法更好?,java,class,methods,setter,Java,Class,Methods,Setter,例如: private int x = 4; public TestClass(int x) { this.x = x; } public TestClass(int x) { setX(x); } public void setX(int x) { this.x = x; } 第一个构造器更好,还是第二个构造器更好?我这样问是因为当我在intellijidea中封装我的类时,如果我以前使用this.x=x,它会将其更改为setX(int-newX)有一个术语叫做

例如:

private int x = 4;

public TestClass(int x) {
    this.x = x;
}

public TestClass(int x) {
    setX(x);
}

public void setX(int x) {
    this.x = x;
}

第一个构造器更好,还是第二个构造器更好?我这样问是因为当我在
intellijidea
中封装我的类时,如果我以前使用
this.x=x
,它会将其更改为
setX(int-newX)

有一个术语叫做自封装。马丁·福勒写了一篇关于这个话题的博客。为了总结这一点,您可以在
setter
中进行初始化或分配逻辑。所以我认为,无论何时要初始化或赋值,最好调用
setter

在很大程度上,这都是个人喜好。如果第一个构造函数的值不依赖于其他变量,我将使用它。但是,setter方法允许在修改变量值之前满足某些条件。例如:

private int x;

public TestClass(int x) {
    setX(x);
}

public void setX(int x) {
    // Some random condition depending on other variables.
    if (System.currentTimeMillis() & 1 == 0) {
        this.x = 5;
    } else {
        this.x = x;
    }
}
如果有许多条件不容易用三元语句表示,那么使用setter方法是有意义的

如果类是抽象的,那么扩展它的具体类可能重写setter方法,从而修改变量的值。如果您计划使用自封装,并且不希望任何子类重写setter方法,只需将
final
关键字添加到方法声明中即可。

这取决于具体情况

派生类可以重写setter,您需要决定重写在特定位置的效果是好是坏


我的意见是,如果setter被证明是可重写的,那么您需要注意使用setter而不是赋值。如果您没有将setter记录为可重写,那么只需使用赋值。

您已经接受了答案,但我仍然看到一些没有人提到的内容。setter使类可变(至少在没有保护条件的情况下),这可能是好事,也可能不是好事。但是,如果将值提供给构造函数,则更容易使类不可变

不可变类本质上是线程安全的,只要可行,就应该首选它。因此,在您的(当然非常简单)示例中,我倾向于使用构造函数,而对于值,我只有一个getter


在我看来,有一个接受值的构造函数和一个设置相同值的setter是一种代码香气,如果不是气味的话。

我通常更喜欢直接赋值,因为它节省了额外的堆栈操作。我通常只在方法的行为比赋值更复杂时才使用方法。可以说调用
setX(int)
更不可预测,因为它可以被任何子类覆盖
setX(int)
可能应该是
final
以防止出现这种情况;我认为为每个字段创建getter和setter,并在包含类中简单地访问它是一种过分的做法。所以我个人会坚持第一个例子
this.x=x。但是当然有人会说这取决于情况。@OusmaneMahyDiaw如果它需要读写,那么我不同意。在setter中使用额外的逻辑是非常不鼓励的,setter应该只使用给定的参数设置字段值-如果您想要额外的逻辑,请使用描述性名称调用该方法。关于额外的堆栈操作/调用方法而不是直接访问字段对性能的轻微影响-我认为实际上不会有任何影响,因为JVM/JIT优化,方法调用可以内联…这是一篇非常有趣的博客文章。以前从未想过这个概念。非常感谢。