This is a question I have had for a while now:
When does it make sense to expose a field publicly like so?
public class SomeClass()
{
public int backi
Here is the summary of pros and cons of public fields:
Advantages
Disadvantages
So when should we use public fields? Depends. It is obvious that for public classes disadvantages outweigh the advantages. Possible problems with evolving the code inside the package are far worse than more clutter in the code and minor performance impact.
However, a class can be package private or even private nested, in which case the probable changes to the code will be localized. Therefore it is absolutely possible to use public fields. Also there are cases when performance difference is not so little. For instance, Android Developers guide claims that it is a good practice to use direct field access instead of getters/setters where it is possible because it is several times faster.
To sum up, I will quote one of my favourite books, Effective Java by J. Bloch, Item 14:
In summary, public classes should never expose mutable fields. It is less harmful, though still questionable, for public classes to expose immutable fields. It is, however, sometimes desirable for package-private or private nested classes to expose fields, whether mutable or immutable.
When does it make sense to expose a field publicly?
Among other places, on private classes as below.
public class MyOuterClass
{
private class MyInnerClass
{
public int val ; // why bother w/boiler plate
}
}
I think it makes sense when you want to group some variables/objects (kind of like a C struct
). For example:
class Pixel {
public int x;
public int y;
Color c;
// Other Pixel related information
}
As there are no methods, nothing breaks if a wrong value is used and it nicely puts these variables together.
On projects with non-trivial complexity it is rarely - but sometimes - a good idea to use public fields. One example that comes to mind:
/**
* A two-dimensional mathematical vector. Immutable so instances may be freely shared
* without violating encapsulation.
*/
public class Vec2 {
public final int x, y;
// bunch of constructors and methods omitted
}
Rationale: It is exceedingly unlikely that the internal representation will need to be changed, or any kind of operation be performed when reading x
or y
. That is, using a setter confers no benefit here.
However it would confer some costs:
One scenario, at least in .NET, is interop with C APIs. You'll often declare C# or VB versions of Windows API structs, and it's common to use public fields for these because the normal reason for making fields private -- to prevent someone messing with them behind your back -- breaks down. In this case, you know that something is going to be changing the fields behind your back -- that's the whole purpose of having the struct!
Of course you typically won't expose those unencapsulated structs to application code -- you'll treat them as private elements of the P/Invoke module, so application code still won't be dealing with the public fields.
One of the scenarios when public field is a better choice is providing constants of your class.
For example, see:
public const double PI
defined in System.Math.
This approach is favored because it explicitly informs consumers of your class, that this member does not include any logic, validation or any other state-related operation, thus can be used in whatever context you want.
The other one I can think of, is when you need classes as containers for simple operations (or just for passing the large number of params to a method), as an example see System.Windows.Point
. In most cases, these containers are modeled as structs though.