I was coding up my own implementation of a LinkedList yesterday. I was doing something like this:
public class Node
{
Node next;
int value;
public Node()
{
next = null
value = 0;
}
}
Then when using the Node
I was doing node.next
and node.value
. Then I realized - wait, what the heck am I doing? These instance variables should be private
and then I should be accessing with getters() and setters() like getNext()
and setValue()
.
This led me to wonder, when is anything other than a private
instance variable desired?
Technically, you're asking two questions: The title question, "When is it appropriate to have a public instance field," and your final sentence, "When is it appropriate to have a non-private instance field."
When is it appropriate to have a public instance field? Just about everyone knows the answer is almost never. I think they occasionally can be appropriate in very small value classes, which behave like simple C structs. A good example would be java.awt.Point and java.awt.Dimension.
Those are in fact especially good examples, because they ended up evolving to use accessor methods despite their simplicity, which is a good lesson: Even a class that seems so simple that public fields might seem acceptable has a real possibility of becoming something that requires encapsulation. (Point and Dimension continue to retain those public fields for backward compatibility.)
When is it appropriate to have non-private instance fields? Most people don't take advantage of the fact that fields and methods (and classes) with no access modifier are package-private, but package-private fields can be useful in a lot of situations. Since they're only accessed by the same package, it will often be the case that it's your code and you can trust yourself not to do "bad things" that would corrupt your objects. I'd say there are considerably more legitimate uses for package-private fields than for public fields.
That said, the Point/Dimension rule still applies: There have been many times when I thought I could get away with package-private fields, only to later realize I needed encapsulation via get- and set-methods.
Protected fields probably get used far more than they should. There's rarely a big gain to let a subclass modify state directly instead of going through a method, in my opinion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With