Simply spoken:
- Avoid static in the first place
- Avoid exposing internal state, too
Having a public writable field is almost a no-go. If you allow multiple components to update that data, then that leads to direct, hard coupling. And it also means that you can (most likely) say "good bye" to thread safety. And even when you think "I will only read that field today"; maybe you forget about that in a few weeks. Or somebody else on your team misses that part. So
So, if you have good reasons to make some data available to the "public"; then at least use a getter method; as that allows for (later) changes. Or it allows for simple enhancements like returning a copy/clone of the internal state (to prevent "outsiders" of manipulating that internal state later on).
Two ways to get around static:
- Think long and hard if you really need global state, or something else could do the job
- If you need global state, then: A) create an interface that denotes the service you want to put up B) create an implementation of that interface as a "normal" class C) then use a singleton (for example an enum) that implements that interface too [ and now the singleton enum can delegate its work to that impl class ]
By following approach 2, you get something that gives you the same functionality (you have a "global" thing that all code can use); but you keep things more decoupled; and most important: you can do reasonable unit-testing all over the place.
static is very often a "killer" for reasonable unit-testing.