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

LTH*_*LTH 53 java coding-style

我的教授真的强调通过始终使用访问器和更改器访问私有实例变量来防止隐私泄露; 但是,我是否必须使用类中的类的getter/setter?

例如,如果我有以下类:

public class Person 
{
    private String name;
    private int age;
}
Run Code Online (Sandbox Code Playgroud)

我想为它编写一个toString()方法.我可以写一下:

public String toString()
{
    return name + " " + age;
}
Run Code Online (Sandbox Code Playgroud)

或者我需要做这样的事情:

public String toString()
{
    return this.getName() + " " + this.getAge();
}
Run Code Online (Sandbox Code Playgroud)

cor*_*iKa 37

你可以做任何一个.但是,您的教授可能会喜欢使用这些方法而不是直接访问.这就是原因.

假设你有一个这样的类:

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;
    }

}
Run Code Online (Sandbox Code Playgroud)

这很简单,对吧?那么,如果我们突然想要改变我们如何计算的实现someValue,并将其基于someString:

public int someValue() {
    int value = 0;
    for(int i = 0; i < someString.length; i++) {
         if(someString.charAt(i) == ' ') value++;
    }
    return value;
}
Run Code Online (Sandbox Code Playgroud)

现在,您还必须更改someValue使用变量的每个位置.

因此,如果您希望从长远来看使代码更易于维护,请使用方法调用.这样,当您对自己进行代码更改(并相信我,它会一直更改)时,您只需要在一个位置而不是两个位置进行更改.

是的,您可能希望someString在最后一个方法中使用方法调用而不是直接访问:-)

  • 虽然这是一个有效的点,但我想补充一点,原始问题专门针对getter和setter,它们应该是副作用的,只返回实例变量,而不是计算值.如果方法计算一个值,那么更好的名称是computeThis,而不是getThis.而现代IDE使得重构多个更改就像单个一样简单. (54认同)
  • @JRL.+500.对于维护者来说,使用成员变量意味着"这里没有惊喜". (11认同)
  • 正如我在回答中所述,方法“getSomething”应该返回“setSomething”设置的值。如果您根据某些条件返回不同的值,那么该方法不应命名为“getSomething”...它应该是“getSomethingMutated”。方法名称“someValue”的描述性不够。方法是一个动作,方法名称“someValue”中没有动词。这就像用动词命名字段,例如“int getValue”。+1 给@JRL 和@Alexander。 (2认同)

Nat*_*hes 19

当我设计一个类时,我试图明确区分内部(实现细节)和外部(暴露给世界的接口).getter和setter提供了一个方便的位置,可以在存储在对象实例成员中的表单与外部世界看到它们的表单之间转换值.在内部使用getter和setter会破坏它,因为它们会被内部和外部使用.

如果您发现自己想要隐藏同一类的另一部分类的一部分,请考虑将要隐藏的部分分解为自己的类.


wax*_*ing 16

由于多种原因,这通常不是一个好主意:

  • 您可能甚至不想要所有字段的访问者
  • 一些访问者可能会制作一个防御性副本,以免暴露内部状态,这通常是在你知道你不会修改它的类中是不必要的 - 或者如果你知道你要修改它就是完全错误的
  • 它使调试更烦人,因为你必须遵循getter/setter
  • 它使得在大多数IDE中更难以读取代码,因为它们中的大多数颜色字段与局部变量不同

......但与往常一样,也有例外.有些setter可能有你想要执行的副作用(例如设置第二个值),那么使用setter可能会更好.此外,如果您将类设计为继承,如果您希望子类能够更改行为,则最好通过访问器.


Pau*_*aul 7

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

public void setName(String name)
{
  _name = name;
}
Run Code Online (Sandbox Code Playgroud)

并且你的getter返回了别的东西,比如

public String getName()
{
  return _name.toUpperCase();
}
Run Code Online (Sandbox Code Playgroud)

那么是的,你应该使用吸气剂.不过,为getter设置更具描述性的名称会更好:

public String getNameAsUppercase()
{
  return _name.toUpperCase();
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*and 5

可以使用访问器和更改器,但它遵循一个混乱的标准.

它会使你的代码变得混乱,并使任何试图阅读它的人感到困惑,认为它可能不是你班级的一部分.

基本上,只需直接从类内部访问变量,间接访问其他任何变量.

  • 这是一个凌乱的标准?如果您不得不以现在无法使用变量的方式更改程序,那么您必须使用方法调用.现在你必须改变课堂上的每一个电话...... (3认同)
  • @glowcoder它在你的班级里面很乱,它总是*可以访问*all*的所有字段. (2认同)

ebo*_*oix 5

不,你没有.您可以从类中访问任何变量,private,public或protected.

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

在此输入图像描述

资料来源:Java教程

  • 真棒的小桌子。我总是忘记“没有修饰符”。 (2认同)
  • 当我写"无修饰符"代码时,人们会看到它并认为它是原型,我只是没有花时间来决定它的访问级别应该是什么.对不起,伙计们,如果我没有考虑谁应该访问它,我不会把变量放在那里,它真的应该是'没有修饰符'.我觉得Java确实犯了一个错误,但这只是因为这给我带来了巨大的不便. (2认同)