user2248702
user2248702

Reputation: 3008

When is using public fields acceptable?

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?

Upvotes: 5

Views: 2252

Answers (4)

Basil Bourque
Basil Bourque

Reputation: 340098

Data-oriented programming

If the main purpose of your class is to communicate data, especially immutable data, then just use public fields. No point in having getter methods.

For more discussion, see Data-Oriented Programming in Java - Version 1.1 by Nicolai Parlog, 2024-05.

record

Indeed, Java 16+ provides a facility specifically for transparently communicating shallowly-immutable data: records.

Here is an example of an entire record class.

record Employee ( String name , LocalDate hired ) {}

Actually, the compiler implicitly provides getter methods for each field, named with the field’s name. So you can access the data either by field or by method call.

Employee alice = new Employee ( "Alice Anderson" , LocalDate.of ( 2025 , Month.JANUARY , 23 ) ) ;
String name = alice.name ;    // Access by field.
String name = alice.name() ;  // Access by method call.

Upvotes: 0

Stephen C
Stephen C

Reputation: 719551

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.

Upvotes: 5

Kyle Anderson
Kyle Anderson

Reputation: 7051

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?

Upvotes: 1

anirudh
anirudh

Reputation: 4176

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.

Upvotes: 1

Related Questions