Java 良好软件实践-获取和设置方法

Java 良好软件实践-获取和设置方法,java,coding-style,Java,Coding Style,如您所见,下面的类声明了2个私有实例变量和2个与每个私有成员关联的get&2 set方法,以允许对它们进行操作和验证 我的问题是:在构造函数中直接使用下面的代码片段中所示的实例变量,还是使用与它们相关联的set方法,以及在toString方法、实例变量或它们的getter方法中使用哪种方法更好 谢谢你抽出时间 public Class Employee { private String firstName; private String lastName; public Empl

如您所见,下面的类声明了2个私有实例变量和2个与每个私有成员关联的get&2 set方法,以允许对它们进行操作和验证

我的问题是:在构造函数中直接使用下面的代码片段中所示的实例变量,还是使用与它们相关联的set方法,以及在toString方法、实例变量或它们的getter方法中使用哪种方法更好

谢谢你抽出时间

public Class Employee {

  private String firstName;
  private String lastName;

  public Employee (String first, String last)
  {
    firstName = first;
    lastName = last;
  }//end of constructor

  public void setFirstName(String first)
  {
    firstName = first;
  }//end of method setFirstName

  public String getFirstName()
  {
    return firstName;
  }

  public void setLastName(String last)
  {
    lastName = last;
  }//end of method setLastName

  public String getLastName()
  {
    return lastName;
  }//end of method getLastName

  public String toString()
  {
    return String.format ("%s: %s %s\n", "Employee Name: ", firstName, lastName);
  }//end of method toString

}//end of class Employee

如果希望扩展类(并且覆盖getter/setter),最好使用方法而不是变量

注意:我不确定构造函数中到底发生了什么,最好直接设置变量


您可以将getter/setter标记为final,这样就不必担心重写。使用这些方法而不是直接访问仍然是一种很好的做法,因为您可以更容易地将断点或调试语句放在那里

我倾向于通过构造进行初始化。通过使用此方法并提供适当的检查(通过
final
进行编译时间检查,通过空检查或类似检查进行运行时检查),您可以确保正确、完整地实例化对象

在字段上使用
final
关键字将使编译器检查您在构建时是否已为该字段赋值。这确实意味着该字段是不可变的,但令人惊讶的是,您经常需要该字段


我会小心地为每件事提供获得者。如果您不断地提供和使用getter,这表明您正在从对象中提取数据,并在该对象之外对其进行操作。请记住——OO的一个关键原则是让对象为您做事,而不是向他们索要数据并自己动手。

规则#1,始终将访问限制在最不必要的范围内,即除非您明确需要更改名字/姓氏的值,否则请使对象不可变(带参数的构造函数,没有setter,只有getter)

我会使用setter。有时setter中会有额外的代码。例如,列表的setter可能也会钩住列表的已更改事件,如果不使用setter,您将无法捕获已更改的事件。

一般来说,我倾向于避免从构造函数调用非静态方法(因为对象在那个阶段没有完全初始化)。如果setter方法只将一个字段设置为参数值,如上文所述,我只需在构造函数中设置它(即不调用setter)。如果setter更复杂,我会尝试将逻辑分解为静态助手方法,并从构造函数和setter方法中使用它。类似于:

 int field_;     

 Constructor(int initialValue) {
     field_ = helper(initialValue);
 }

 public void setField(int value) {
     field_ = helper(value);
 }

 // not really complex, but avoid duplication of logic
 private static int helper(int value) {
     return 2*value;
 }

谢谢Attila的回答!!可能会向你提出另一个问题-关于字符串的验证-从你的经验来看,你在代码中寻找哪些东西来验证字符串!!再次感谢你。你想验证什么?顺便说一句,你最好把这个问题作为一个新问题发布,并给出更详细的解释除此之外,根据经验,不鼓励在构造函数中使用可重写方法,因为这会使代码完全不可维护(至少在我遇到的那些情况下是这样的…)谢谢Brian的时间和解释。这很有帮助。这是一条好规则,但我想说这是本例的重点之外的一条。