4

What is the standard approach/best practice to creating variables that are program- or package-wide in Java?

I want to set up some global variables that are accessible by multiple classes. Examples of these global variables would be things like a boolean flag testModeOn, a language setting, current local server, time display format, etc. According to some other questions (namely this one) there aren't any global variables, but there are some work-arounds using interfaces (not recommended?) or classes. Since the original poster didn't explain their situation, they got nearly every answer under the sun and I want to ask specifically for program configuration variables.

Is it better to create a class/package/interface and then import it into my working class/package? Is there anything I should be aware of when trying to implement these variables using a separate class or interface? Is there any other way to fudge package-level variables since Java apparently doesn't do this natively?

NOTE: These variables would probably not change except when the program is re-compiled.

Community
  • 1
  • 1
Alium Britt
  • 1,246
  • 4
  • 13
  • 25
  • The Singleton pattern. – Smutje Jun 22 '14 at 11:21
  • By "singleton pattern", you mean I should create a class that only ever has one instance/object created? – Alium Britt Jun 22 '14 at 11:26
  • Yes, and this class contains global settings which can be accessed through this single class. Additionally, the singleton can care about persisting or serializing the settings if desired. – Smutje Jun 22 '14 at 11:28
  • 1
    @Smutje no way. Do never use a singelton http://c2.com/cgi/wiki?SingletonsAreEvil and http://i.stack.imgur.com/Dzdio.png – Zarathustra Jun 22 '14 at 11:31
  • 1
    @Zarathustra "Don't instantiate a second instance." good one, never worked with real-life problems I assume - sometimes it's best to enforce something rather than "hope for the best". – Smutje Jun 22 '14 at 11:34
  • 1
    @Smutje I don't agree that the Singleton pattern is relevant here. Using `static` fields means that no object instance needs to be created at all, so the Singleton object would not even be required. – Bobulous Jun 22 '14 at 11:35

4 Answers4

3

If you're talking about constants, then they should be declared as static final fields in a class (never in an interface, according to Joshua Bloch).

If you're talking about settings which can change on the fly, then these could be either static fields in a class, or you could create a ConfigHandler class to manage the setting and fetching of configurable values.

Using class fields for mutable values might lead to concurrency problems, so if your application is multi-threaded it might be better to create a ConfigHandler class which manages concurrent access carefully and provides synchronized methods to avoid problems.

Bobulous
  • 12,967
  • 4
  • 37
  • 68
  • These variables would probably not change except when the program is re-compiled, so I'm not worrying about mutability issues so much but I'll keep them in mind. – Alium Britt Jun 22 '14 at 11:29
  • 1
    Then the values are constants, and defining these values as `static final` at the top of an appropriate class would be the best way forward. Don't forget that `final` does not stop the content of a Collection or Array being modified, so you may need to see the documentation for the [java.util.Collections class](http://docs.oracle.com/javase/8/docs/api/java/util/Collections.html) which offers a set of methods called unmodifiableXxxx which let you create Collection objects that do not allow their contents to be rearranged. – Bobulous Jun 22 '14 at 11:33
  • I think I'll be primarily be using integers, strings and booleans, but I'll take a look at the collections and arrays docs. I have a tendency to use arrays a lot in my programs so I might need to add a comment inside this class to remind myself to pay attention to mutability if using an array sometime in the future. Thanks! – Alium Britt Jun 22 '14 at 11:44
  • Since this class would only exist to hold my config variables, would I also declare this class as `static final` as well? And how would I reference the variables in this class - `MyClass.myStaticField`? – Alium Britt Jun 22 '14 at 12:17
  • A class cannot be `static` so don't worry about that. And you're right that you reference static fields using the name of the class. See [Understanding Class Members](http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html) for a fuller explanation. – Bobulous Jun 22 '14 at 15:40
1

In my opinion, the best approach to passing anything into your classes is using dependency injection. This would eliminate your need for Singletons, static constants and the likes.

Depending on which DI you favor, here are some link solutions to the problem you describe:

ethanfar
  • 3,733
  • 24
  • 43
-1

Create a Bean class if multiple variables are required to be used in different classes. Best practice is to create a private variable with its getters and setters.

public class ListBean implements Serializable
{
    private boolean testModeOn;
    public boolean getTestModeOn()
    { 
       return testModeOn;
    }
    public setTestModeOn(boolean testModeOn)
    {
        this.testModeOn = testModeOn;
    }
Zarathustra
  • 2,853
  • 4
  • 33
  • 62
robinrjoe
  • 329
  • 2
  • 14
-2

In general there are so many ways to do it wrong regarding this topic.

The simple way is to use a Singelton. This is not an option - Singelton is an Anti-Pattern. http://c2.com/cgi/wiki?SingletonsAreEvil

So what is else there? An Interface with public static final variables? Not an option - Thats simply not the use case of an interface: https://stackoverflow.com/a/2659740/1248724

so what is else there? The answer is:

enter image description here

What I prefer is the spring boot way (e.g. Dependency Injection) Here an code example which is obviously Spring.

import org.springframework.stereotype.*
import org.springframework.beans.factory.annotation.*
@Component
public class MyBean {
 @Value("${name}")
 private String name;
 // ...
}

If you are using some similar Framework such things could be easy archived.

If that is somehow not possible in your environment I had to code something like this:

public final class Configuration {

private Configuration() {
    // make sure there is no instance of this class
}

    public static final MySetting<DateFormat>   setting = new SampleProperty();

    public interface MySetting<T> {
        T get();
    }

    private static final class SampleProperty implements MySetting<DateFormat> {

        @Override
        public DateFormat get() {
            return new SimpleDateFormat("...");
        }

    }

    // other inner classes that implement the MySetting interface
}

public static void main(final String[] args) {
     Configuration.setting.get();
}

Benefits: - You can validate your properties how ever you want. - You can work with the java security manager if you like to

Downsides: - You may have to maintain a bunch of code (this should be easier with lambda expressions) - Not that great as the way spring offers here for example.

A very similar approach I just found: https://stackoverflow.com/a/3931399/1248724

Community
  • 1
  • 1
Zarathustra
  • 2,853
  • 4
  • 33
  • 62
  • While this may be good advice about avoiding the use of Singletons, you're not actually providing an alternative answer here. This chart only shows me that I shouldn't use a Singleton. Since you've eliminated the other possibilities, should I assume that you suggest using a class instead? – Alium Britt Jun 22 '14 at 11:48
  • And by "suggest using a class" I mean "suggest using a normal class". – Alium Britt Jun 22 '14 at 12:00
  • 1
    seems you are trying to express your hatred towards singletons and not really providing an answer. Singleton is an accepted pattern and like any other design pattern, it "can be evil" when used in an improper way/place. You better know the pattern properly and learn where to and where not to used rather than just rejecting it for all! – mohamnag Aug 21 '17 at 08:45
  • @mohamnag here another good conclusion .. https://dzone.com/articles/what-the-singleton-pattern-costs-you – Zarathustra Aug 24 '17 at 09:45
  • @Zarathustra sorry but DZone is so commercial that I would rather not use it as a reference. Like here when he is comparing singleton to field injection and concludes later is better OO than the former!!! – mohamnag Aug 25 '17 at 07:44