Mechanically wrapping a variable in a getter/setter is the same as making it public.

Not exactly. When wrapped there is an option to override and do additional work when getting and setting the value. (e.g. fancy caching of calculated values, marking the data as having changed or calling change Listeners.) This option is not available if you simply make the value public.In general getters and setters are inlined at runtime so there is little or no penalty for using them, yet they provide you with hooks that might be useful in derived classes or if the implementation needs to change.

Like Herkules said, the cases for actually using a public variable exist.. e.g. when you have something that is only a data structure (has no methods at all) that you want to treat as a unit. You may still have get/set methods in some other class that operate on this 'data' class.Look at java.awt.Dimension for example. It is a trivial data structure, there isn't any need to code for future extendability or anything because of the simplicity of the data you are dealing with.

I agree with what's said here, but I think you should still be very careful not to start creating public members all the time. Especially with extending classes, you will make your code unreadable and very error prone. For example you will easily be doing 'a *= 2' instead of 'super.a *= 2' creating a bug when you have another 'a' in your sub class.Better to use private members with getters and setters (setters of course as little as possible) by default and public members only in some circumstances where it makes sense.

In addition to the hooks argument (lets you facade classes), there's the JavaBeans argument.

If all your var's are accessed via get/set, then another app/library can use reflection to determine which vars you want people to access, and then on top of this can use the hooks to do fancy stuff - e.g. stuff which you want to do to almost ALL classes, e.g. persistence.

The examples I encounter most often are persisting data to a database and object-serialization for network transfer. In both these cases it's rather nice when you have a library which can transparently create stubs for you that e.g. read the data from the DB whenever it's needed (by overriding the methods).

However...I'm suffering a backlash against get/set's at the moment simply because of their long-windedness. It's all NIO's fault (note: NIO breaks Sun's own recommendations / coding conventions in this regard; it simply ignores the whole get/set thing). If you want to get the limit of a buffer, you use "limit()", if you want to set the position you use "position( int )", or "position()" to get it. You soon get used to reducing your typing by 2 to 4 chars for every access (normally you have to type at least "g" and sometimes the "et" as well before hitting your autocomplete button to get you to where you can start typing the variable name).

This is particularly obvious on short var names - like "a". If you have methods or vars somewhere in your environment (e.g. all public members of imported classes) called "gabby" and "gershwin", then to type "getA()" you need to type five chars minimum. If you just used "a()" then you only need type 2. That's a big difference when writing data-manipulation classes! (especially controllers and views).

The examples I encounter most often are persisting data to a database and object-serialization for network transfer. In both these cases it's rather nice when you have a library which can transparently create stubs for you that e.g. read the data from the DB whenever it's needed (by overriding the methods).

I agree. This is exactly the case that we are using, with "heavyweight" objects that are persistent and/or serializable, and "lightweight" objects that just live for the current session. We have had times that we made a whole bunch of heavyweight objects into lightweight ones, and vice versa. Because we use get/set methods *everywhere* this didn't impact any of the other code because it was all an implementation detail within the objects themselves. It saved having to edit dozens of other files to change "blah.value" to "blah.getValue()".

As far as speed of development vs. ease of maintenance and refactorability, I will always choose the latter -- probably because I expect my code to last for several years. As far as performance, my understanding is that the JVM will pretty much always in-line trivial get/set methods, so there's no difference in runtime performance. Perhaps there's a small overhead in the class size.

That said, I agree with Herkules that if you want to communicate to the user of your object that there is no hidden side-effects of accessing or setting the data member, then you can make it public. In practice, whenever I have done so, I almost always end up making it a getter/setter eventually.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org