Java是否可用public成员变量?
《C++沉思录》有个脚注提到作者本人在某种情况下出于实际考虑使用了public成员变量,为了严谨,我不应该用“有个脚注”这种说法,所以又特意翻了书,是《C++沉思录》的第16页的脚注,人民邮电出版社2002年第一版。
这条脚注是这样的:
细心的读者可能会发现我把数据成员设为public,并为此惊讶。我是故意这样做的:machine_status是一个简单的类,其结构就是其接口。对于如此简单的类来说,把成员设为private没有任何好处。(从这个小小的脚注可以看到作者的实用主义态度,相对于后来很多人所奉行的教条主义,确实有很大的差别——译者注)。
是的,不仅原作者这么说,而且连译者都表示了赞同。
于是,这就在我脑海里埋下了一个种子,以至于后来写Java的时候,对于一些小的类(那种通常命名为Element的类),也会使用public成员变量。然后有一天我开始怀疑这种做法,就到网上查,我是应该使用public成员变量?还是使用private成员变量,并给出getter和setter方法?
http://www.cs.swarthmore.edu/~newhall/unixhelp/javacodestyle.html 这里说:
Data members should be private. Only under unusual circumstances should data members be public or protected; instead, you should create public and protected accessor/modifier methods to read/write an object's private data members. One exception to this rule is that static final data members can be public or protected.
http://programmers.stackexchange.com/questions/143736/why-do-we-need-private-variables 这里还有一个关于private variable的讨论,也是支持private而不是public。
由此看来似乎应该使用private并给出getter和setter。
但是上面链接中有个人提到
In traditional lanugages like C++ or Java, you usually make everything private and only accessible by corresponding getters and setters. No need to decide much really.
Sometimes, f.ex. in a C++ struct, you need a class only as a way to group several things together. For example, consider a Vector class which has an
x
and ay
attribute only. In those cases, you may allow direct access to these attributes by declaring them public. In particular, you must not care if some code outside modifies an object of your class by directly writing new values intox
ory
.
其中第2点就挺符合我的那种情况……
但是最终我的结论还是倾向于用private,并用setter和getter,这个setter其实也是破坏了封装性(而public成员变量是根本没有封装性),但是如果真的不需要的话,你可以选择不要它。而且使用setter应该比直接将某个成员设为public更好,好处是你可以控制,比如添加验证参数是否合法,如果暴露为public,是完全无法控制的。举例来说,如果有个setNumberOfPeople(int num)方法,你就可以检查num是否非负,负数就是非法的;如果暴露为public,是做不到这一点的。
http://stackoverflow.com/questions/1568091/why-use-getters-and-setters 这个似乎回答的正是我的问题,被最多人认可的回答也是要setter和getter。这里提到了这样做所带来的更多的好处,虽然有些都没接触到。
其中有这样一个comment,虽然没这么用过,但觉得不错:
One thing that is bought by using a property setter, even in a well-designed framework, is the ability to have an object notify another when a property changes
不过往下看的话,还是会发现有很多争论和另一种看法的支持者……
Anyway,我比较倾向的结论是:用private成员变量,并只在必要的时候给出getter和setter方法;这种做法似乎没有明显的缺陷。
更多参考:
http://stackoverflow.com/questions/11071407/advantage-of-set-and-get-methods-vs-public-variable
http://stackoverflow.com/questions/565095/are-getters-and-setters-evil
http://www.javaworld.com/javaworld/jw-01-2004/jw-0102-toolbox.html (这个不错)
http://typicalprogrammer.com/?p=23 (特别提到Java和python的对比,Java可能还是需要getter和setter,因为如果开始用public member,等你想改变主意用getter和setter,就有点迟了,因为可能已经写了很多“classInstanceXXX.memberYYY = ZZZ”这种代码)
Google “java public member vs setter getter”