为什么不直接使用该属性,而是使用getXXX()方法

时间:2011-10-21 08:43:53

标签: java encapsulation

在某些域对象的方法中,他们没有直接使用该属性,而是使用get方法。为什么?一个例子如下:

private List<String> errorCodeList = new ArrayList<String>();  

/** 
 * Add all errors to the error list.
 */
public void addAllErrors(Collection<String> theErrorStrings) {
    if (errorCodeList == null) {
        errorCodeList = new ArrayList<String>();
    }

    for (String aString: theErrorStrings) {
        getErrorCodeList().add(aString);
    }
}


/**
 * @return the errorCodes
 */
public List<String> getErrorCodeList() {
    return errorCodeList;
}
/**
 * Set the error strings.
  */
public void setErrorCodeList(List<String> allErrors) {
    this.errorCodeList = allErrors;
}

6 个答案:

答案 0 :(得分:2)

这是一个封装问题。通过仅通过getter和setter提供对实例变量的访问,您可以隐藏内部表示。因此,您可以在不修改界面的情况下更改实现。您可能会认为使用HashMap存储错误代码(无论出于何种原因)会更方便,一旦您更改了该错误代码,访问该字段的所有代码都将中断。但是,如果您提供了getter和setter,那么即使您更改了内部表示,也可以保留它们。

除了更容易确保不变量保持在原地之外,如果每个人都可以访问这些字段,则无法做到这一点。

答案 1 :(得分:2)

我个人不喜欢通过他们的getter方法访问同一类中的字段:封装不会因为你在中编写代码而避免调用getter而被破坏相同的班级定义。此外,使用getter会使代码看起来更混乱,并且无法提供有效的语法突出显示。

显然,您必须通过getter访问该字段:

  • 当它懒洋洋地创建时。
  • 当getter动态计算一个值时。

答案 2 :(得分:2)

我认为示例代码不是最好的方法:通过相同的方法通过getter直接访问变量 - 这种混合有点令人困惑。
如果在getter中完成列表的延迟创建以及使用getter的原因会更清楚。示例:

public void addAllErrors(Collection<String> theErrorStrings) {
    for (String aString: theErrorStrings) {
        getErrorCodeList().add(aString);
    }
}

public List<String> getErrorCodeList() {
    // TODO synchronization?
    if (errorCodeList == null) {
        errorCodeList = new ArrayList<String>();
    }

    return errorCodeList;
}

答案 3 :(得分:0)

这就是封装:

  

封装可以被描述为防止的保护屏障   由定义的其他代码随机访问的代码和数据   课外。严格控制对数据和代码的访问   通过界面。

提供更多信息here

答案 4 :(得分:0)

在调用中使用getter是一种好习惯,getter是否存在。这是因为如果getter背后的实现是要更改使用getter的类中的其余代码则不需要更改。

它还可以简化静态代码分析,因为所有对字段的访问(来自类内或不使用)都是通过单一方法完成的。

当然有额外方法调用的权衡(除非编译器足够聪明以进行转换)。

那就是说,我同意亚当斯基,我也不是这个的粉丝。

答案 5 :(得分:0)

直接访问数据成员不会破坏封装,但是几个月之后,数据成员会改变语义,你必须在一百个派生类中搜索,直接访问该字段确保没有什么破裂?如果仅通过getter进行访问,则跟踪每个字段的访问位置要容易得多。