When does it make sense to use a public field?

后端 未结 8 1207
北恋
北恋 2021-02-18 17:02

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         


        
相关标签:
8条回答
  • 2021-02-18 17:06

    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:

    1. The public final field will make it abundantly clear the class is immutable, with a getter, you have to trust the documentation comment. (Do note that the absence of a setter does not imply immutability, because some other method might assign the field)
    2. Code accessing the vector would be slightly less readable, as get() confers no meaningful semantic information, but still has to be skipped over when reading the code (at least in Java, C# is better here).
    3. This being an extremely low level class frequent use is possible, and invocation overhead might become an issue. Yes, the virtual machine can perform inlining in many cases, but at least for non-final methods, some overhead is likely to remain even if no subclasses are currently loaded.
    0 讨论(0)
  • 2021-02-18 17:12

    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.

    0 讨论(0)
  • 2021-02-18 17:13

    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
          }
    }
    
    0 讨论(0)
  • 2021-02-18 17:13

    So the best answer I can give is that when you do magic via reflection, as one is wont to do when taking advantage of a statically typed language, properties have meaning over fields. From things like ORM tools, to mappers, and to binding data, properties can have different meaning than fields from that behavioral standpoint.

    The JITter doesn't turn properties into fields, it can inline them, though I won't promise it does in all cases.

    0 讨论(0)
  • 2021-02-18 17:15

    Here is the summary of pros and cons of public fields:

    Advantages

    • Less clutter in the code
    • Better performance (in some cases)

    Disadvantages

    • Representation can't be changed without changing the API
    • Invariants can't be enforced (unless the field is immutable)
    • No additional actions can be taken when accessing these fields

    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.

    0 讨论(0)
  • 2021-02-18 17:18

    In my opinion, when you design a structure of a class you should pay more attention to future changes and should always be friendly to them. If a future requirement need you to do some logic before returning a value instead of just returnning the value of the field, you'll have to change the interface of the class, and all users of your library will have to change. That usually become a disaster.

    Keep in mind, the open / close principle.

    0 讨论(0)
提交回复
热议问题