Java约定:在类中使用getter/setter?

Java约定:在类中使用getter/setter?,java,coding-style,Java,Coding Style,我的教授非常强调防止隐私泄露,总是使用访问器和变异器访问私有实例变量;但是,我必须在类中使用类的getter/setter吗 例如,如果我有以下类: public class Person { private String name; private int age; } 我想为它编写一个toString()方法。我可以写下: public String toString() { return name + " " + age; } 或者我需要这样做: public

我的教授非常强调防止隐私泄露,总是使用访问器和变异器访问私有实例变量;但是,我必须在类中使用类的getter/setter吗

例如,如果我有以下类:

public class Person 
{
    private String name;
    private int age;
}
我想为它编写一个toString()方法。我可以写下:

public String toString()
{
    return name + " " + age;
}
或者我需要这样做:

public String toString()
{
    return this.getName() + " " + this.getAge();
}
class SomeClass {
    private int someValue;
    private String someString;

    public SomeClass(int someValue, String someString) {
        this.someValue = someValue;
        this.someString = someString;
    }

    public int someValue() {
        return this.someValue;
    }

    public String someString() {
        return this.someString;
    }

    public String toString() {
        return someValue + ": " + someString;
    }

}

不,您可以在类中直接使用实例变量,您没有违反任何“规则”。其他类必须使用getter和setter来访问类的实例变量,以避免违反封装原则(这在OO编程中非常重要)

最后,这是一个选择的问题,但您使用第一个示例保存了一个方法调用。

您可以使用访问器和变异器,但这是一个混乱的标准

它会把你的代码弄得乱七八糟,让任何试图阅读它的人都觉得它可能不是你课程的一部分


基本上,只需直接从类内部访问变量,间接地从其他地方访问变量。getter/setter的动机之一是底层数据存储可以更改,并且实现类的内容不需要更改,因为它是封装的

因此,记住这一点,在类中使用getter/setter可以使将来的更改更容易。您不必直接查找所有改变成员的位置,只需更改getter/setter即可。根据类的复杂性,这可能会显著减少更改存储成员所需的工作量

例如,假设您从年龄变量开始,以年为单位。然后,出于某种原因,您决定稍后将其存储为秒。但无论如何,你都想在几年内把它打印出来。因此,在您的示例中,您可以在toString()函数中进行计算(以及任何希望以年为单位的其他地方),或者您可以在getAge()例程中更改数学,以从秒返回年,而无需更改任何其他内容


显然,这个例子有点微不足道。类越复杂,在其中使用getter/setter就越有用

不,你没有。您可以从类中访问任何变量,私有、公共或受保护

以下是一些帮助您的表格:


您可以选择其中一种。但是,您的教授可能会喜欢使用这些方法,而不是直接访问。原因如下

假设你有这样一门课:

public String toString()
{
    return this.getName() + " " + this.getAge();
}
class SomeClass {
    private int someValue;
    private String someString;

    public SomeClass(int someValue, String someString) {
        this.someValue = someValue;
        this.someString = someString;
    }

    public int someValue() {
        return this.someValue;
    }

    public String someString() {
        return this.someString;
    }

    public String toString() {
        return someValue + ": " + someString;
    }

}
这很简单,对吧?那么,如果我们突然想改变计算
someValue
的实现方式,并以
someString
为基础,该怎么办呢

public int someValue() {
    int value = 0;
    for(int i = 0; i < someString.length; i++) {
         if(someString.charAt(i) == ' ') value++;
    }
    return value;
}
public int someValue(){
int值=0;
for(int i=0;i
现在,您还必须更改使用变量
someValue
的每个位置

因此,如果希望使代码更易于长期维护,请使用方法调用。这样,当你的代码发生变化时(相信我,它一直在变化),你只需要在一个地方而不是两个地方进行改变


是的,您希望在获取
someString
时使用方法调用,而不是上一个方法中的直接访问:-)

一般来说,不是。如果您的getter返回的不是字段值,那么您应该使用该方法,但在极少数情况下,您的方法应该具有更具描述性的名称。举个坏例子,如果您有:

public void setName(String name)
{
  _name = name;
}
你的getter还返回了其他东西,比如

public String getName()
{
  return _name.toUpperCase();
}
那么是的,你应该使用getter。不过,最好对该getter使用更具描述性的名称:

public String getNameAsUppercase()
{
  return _name.toUpperCase();
}

当我设计一个类时,我试图在内部(实现细节)和外部(向外界公开的接口)之间做出明确的区分。getter和setter提供了一个方便的位置,可以在对象实例成员中存储它们的表单和外部世界看到它们的表单之间转换值。在内部使用getter和setter会弄糟这一点,因为内部和外部都会使用它们


如果你发现你想把一部分的一部分从同一个班级的另一部分隐藏起来,考虑把你想隐藏的部分分解成它自己的类。

这通常不是一个好主意,有很多原因:

  • 您甚至可能不希望所有字段都使用访问器
  • 有些访问器可能会创建一个防御性副本,以便不暴露内部状态,这在您知道不打算修改它的类中通常是不必要的,或者如果您知道要修改它,则是完全错误的
  • 这会使调试更加烦人,因为您必须遵循getter/setter
  • 这使得在大多数IDE中读取代码更加困难,因为大多数IDE的颜色字段与局部变量不同
。。。但和往常一样,也有例外。某些setter可能有您想要执行的副作用(例如设置第二个值),那么最好使用setter。另外,如果您设计类是为了继承,那么如果您希望子类能够改变行为,那么最好通过访问器进行访问。

如果您的类(或所讨论的访问器方法)不是
final
,那么您一定应该使用访问器方法


如果另一个类扩展了您的类并重写了这些访问器,那么您的类应该使用被重写的访问器。如果这会破坏你的超类,那么你的超类设计不正确;防止那些访问器被
final
覆盖,或者更改类的设计。

我认为我们应该使用
getters()
setters()
而不是直接访问。我
setName(name){

     this.name=name;
     this.listener.nameChanged(this.name); //we call listener that variable changed
 }