4

I have a main class that has a thread pool, which is used by quite a few other classes for performing actions on a database. I currently have a getter method to get the pool which works fine but seems a bit clumsy.

Are there any circumstances where it is acceptable to use a public field instead of getter/setter methods?

Makoto
  • 104,088
  • 27
  • 192
  • 230
user2248702
  • 2,741
  • 7
  • 41
  • 69
  • 4
    final constants for example don't need setter & getter – donfuxx Apr 22 '14 at 03:12
  • If you want to and there's no specification that would prevent it. There's nothing inherently wrong with public fields, it's just not advised if one is intending to produce a "secure" API that can't be subverted by using interfaces contrary to your intent. – Hot Licks Apr 22 '14 at 03:13
  • I think this is an opinion based question to be honest. Whether or not you use the public modifier is really up to you and your development team. If you are writing a libary that is intended to be used by the general public, then you need to avoid giving public access to fields that can change the state of your object. If this is something that will only ever be used internally then it's up to your development team. You should document that changing the values of public fields may have strange effects so only do so if you know what you are doing. – Jared Apr 22 '14 at 03:13
  • I think a better alternative may be using a package level modifier (i.e. no modifier) so that only classes within this package have direct access. – Jared Apr 22 '14 at 03:14

3 Answers3

4

Are there any circumstances where it is acceptable to use a public field instead of getter/setter methods?

The main reason that public fields are bad are that they expose the implementation to the outside world. That leads to unwanted coupling; i.e. classes that are overly dependent on the implementation details of other classes. That tends to make code harder to understand and harder to change. And if the field is not final, you need to search the entire code-base to be sure that nothing is "interfering" with the field. (OK, IDE's make this easier ... but contrast a public field with a private field that has no setter.)

A secondary reason is that you cannot override a field. Once you have exposed a field in a superclass, there is nothing you can do in a subclass can do to modify or restrict its meaning. (By contrast, getters and setters can be overridden ...)

The only situation where it is acceptable (from a stylistic perspective) to have "public" fields is when the class which declares the fields is a private nested or inner class. The consequence is that all dependencies on the field are restricted to the source file that contains the declaration ... which negates the problems above.

UPDATE - I forgot public static final ... but we tend not to think of those as fields at all. Anyway, it is normal practice to access public static final fields directly. The idea of a constant is to deliberately expose the name, type and value ... and the override issue doesn't apply because of the nature of static fields.


I currently have a getter method to get the pool which works fine but seems a bit clumsy.

"Clumsy" is a matter of opinion / taste. Personally, I don't think that obj.getInstance() is clumsy compared with obj.instance. It is just the Java way1.

The flipside is that if you didn't have a getInstance() method, all of the classes that used the pool would have to have hard-coded references to the instance field. If (for some reasons) you needed to change something about the way the pool was accessed (e.g. add a security check, add a counter, make pool creation lazy, make sure that access is properly synchronized), then you have to change each and every place where you have coded reference to the field. But with a getter, you just have one place to change.

1 - Obviously, other languages do this differently. But you are not writing those languages. Java is what it is.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

There are many reasons for using getter & setter instead of a public field. One I've found in SO is

Because 2 weeks (months, years) from now when you realize that your setter needs to do more than just set the value, you'll also realize that the property has been used directly in 238 other classes :-)

You can also have a look at this post, which also quotes that i've give above and provides a few other examples. Read and then you can decide whether to use a public field in your case.

Community
  • 1
  • 1
anirudh
  • 4,116
  • 2
  • 20
  • 35
  • 1
    But in reality the likelihood of such an occurrence is incredibly low. – Hot Licks Apr 22 '14 at 03:15
  • yeah I know, that is why I said that the decision of whether to use public field is upto the developer. – anirudh Apr 22 '14 at 03:18
  • For things such as a string it makes sense to encapsulate them but for something like a thread pool it doesn't make sense (for me anyway) to do something like someInstance.getThreadPool().execute(...) when you could just do someClass.threadPool.execute(...). – user2248702 Apr 22 '14 at 03:18
  • If you have a getter method which returns the `ThreadPool` object then you have already _almost_ given public access to the object: they cannot overwrite the object with the getter method but they can modify the object (by calling methods on it). It might be more appropriate to have the object execute the thread for `someInstance`, i.e. have a method such as `executeInstance(Object someInstance)` and then this method executes with the internal thread pool on the parameter's behalf. – Jared Apr 22 '14 at 03:25
1

Keeping your class fields private and using getter/setter methods provides a layer of abstraction and makes it easier to maintain in the long run. See this: What's the deal with Java's public fields?

Community
  • 1
  • 1
Kyle Anderson
  • 6,801
  • 1
  • 29
  • 41