2

What is a better solution?

I was thinking about that, what is actually better on performance, or which is more "correct"?

public static List<String> globalUseVariable;

or

private static List<String> globalUseVariable;
public static List<String> getGlobalUseVariable() {
    return globalUseVariable;
}

I think the second one because of encapsulation rule?

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
SocketByte
  • 335
  • 4
  • 12
  • 3
    You should probably make it `final`, but then it's a matter of opinion. No difference (really) in performance (the method call is *slightly* slower). – Elliott Frisch Feb 11 '17 at 19:28
  • emphasis on slightly – SaggingRufus Feb 11 '17 at 19:29
  • @SaggingRufus *Agreed*. – Elliott Frisch Feb 11 '17 at 19:29
  • 1
    Some one has to say that the _correct_ solution is to **not** have global state variables at all. I believe the answer here sums it all up: http://stackoverflow.com/questions/7026507/why-are-static-variables-considered-evil – JChrist Feb 11 '17 at 19:32
  • 2
    You also need to consider if you want to allow the consumer of this list to modify it. If not you probably want to hand out a copy or a immutable wrapper. Copies have the advantage that you do not need to care about concurrent modifications. However it all depends on the context if it is needed or overhead. And of course avoiding `static` like the pest. – eckes Feb 11 '17 at 19:32
  • 1
    @eckes Yeah, that makes a lot of sense to me! – SocketByte Feb 11 '17 at 19:33
  • 1
    @GhostCat I don't agree with the dup hammer. – Chetan Kinger Feb 11 '17 at 19:36

3 Answers3

4

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:

  1. Think long and hard if you really need global state, or something else could do the job
  2. 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.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
1

Using getters is advised because there is a chance that you will want to make changes to the class without changing the API or that you will decide that some kind of a conversion should be performed before returning the list. Have a look at this answer regarding a similar situation. In my opinion the same principle generally applies to static fields, there is really no reason to make an exception for them. This question also touches the same topic. I think that the reasons outlined there apply to the static fields as well and are completely reasonable.

In general if you make something public you create a public API and should guarantee that it is unlikely to change to save yourself from a major headache later on (and changes might even be impossible if you are creating a public library and have to be backwards-compatibile).

Additionally using getters and setters you can ensure that the code you write will be thread secure, as mentioned in the other answers and the linked questions. You can't do anything about it when you expose public fields.

Community
  • 1
  • 1
boreq
  • 791
  • 2
  • 10
  • 18
  • We are talking about `static` getters here though. – Chetan Kinger Feb 11 '17 at 19:34
  • The only situation in which I would consider dropping the getters and setters would be if we are talking about some kind of configuration values stored in `final` fields and you really don't want to use getters for some reason (to make it contain less code I guess, but I wouldn't do it personally). All the reasons mentioned in the linked questions apply to the static fields just the same. – boreq Feb 11 '17 at 19:38
  • 1
    Just a hint: that new crazy concept about vertical spacing (old-schoolers call it "paragraphs") helps dramatically with making your content more human readable. Just saying ... – GhostCat Feb 11 '17 at 19:47
  • @boreq What's the point of a getter if the code outside the class can modify the `List`. See my answer. – Chetan Kinger Feb 11 '17 at 20:02
  • The point of it is that that getter doesn't have to return that particular list. In future you might want to change it to return something else entirely. That would normally be a breaking API change, something that can't be done in very large codebases or in libraries. The thread safety or preventing the list from being modified by copying it are additional problems solved by the issue as I said. Not using a getter is just bad practice really, at least in my opinion and other people seem to agree with me if you look at the answers that I linked. – boreq Feb 11 '17 at 21:16
  • @boreq What are you talking about? If the getter returns anything other than a `List` implementation, you are going to break calling code. So the getter can only return an implementation of `List`. You don't need a getter to be able to change what implementation to use. A `public static final List` reference can refer to any list without breaking client code. The getter is pointless if you return a modifiable list! Returning an unmodifiable list is mandatory if you are using a getter and your answer doesn't mention that even once! No thread safety if client can modify the list either!! – Chetan Kinger Feb 12 '17 at 07:02
1

which is more "correct"?

As your code stands, I agree with neither. You gain nothing from marking your List as private and then returning a reference to the same List within a method. You can't call this encapsulation because no matter what logic you add inside the method, you are returning the List reference back to the caller to modify as they please. The least you can do is ask your method to return an unmodifiable collection (using Collections.unmodifiableList) if you want to truly adhere to encapsulation.

If you want your list to be public, the least you can do is mark it as final so that code outside your class cannot attempt something like YourClass.globalUseVariable=null and break any code that uses the List.

Chetan Kinger
  • 15,069
  • 6
  • 45
  • 82