Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reload static fields in a java class

Tags:

java

static

I have a class in java which has a number of static final strings and one static Locale variable.

These Strings are basically keys to a messagebundle which return the translated Strings using the locale.

i.e.,

public static Locale locale = Locale.getDefault();
public static String MSG1 = Translator.get(locale, "MSG1");
//Similar Strings.

This locale variable is set at runtime based on the browser locale. But since these are static variables, they are already initialized with the default locale and changes to the locale variable does not have any effect.

Is there a way to "reload" these strings everytime the localevariable is changed?

I don't want to make the obvious change(making all the strings non static and initializing locale in constructor/method) because this class has a lot of messages(250+) and is used in too many places.

like image 590
cmn Avatar asked Feb 26 '14 10:02

cmn


People also ask

How do you reload a static class in Java?

You can try this. Main MainObject = new Main; MainObject. main(args); It will restart the class again and again until you stop the class.

Can static fields be updated Java?

This is because the assignment of static fields happens once the class is loaded (occurs only one time) into the JVM. The PRIVATE_AREA variable will not be updated when the DOMAIN variable is changed.

Can static variables be re initialized in Java?

Declaring variables only as static can lead to change in their values by one or more instances of a class in which it is declared. Declaring them as static final will help you to create a CONSTANT. Only one copy of variable exists which can't be reinitialize.


1 Answers

Yes. While you can't get Java to run the assignments again, you can move the assignments into a method instead:

public static String MSG1;

public static void setLocale(Locale locale) {
   MSG1 = Translator.get(locale, "MSG1");
}

static {
    setLocale( Locale.getDefault() );
}

After that, you can use the method setLocale() to switch the locale. When the class is loaded for the first time, the locale is set using the static initializer block at the end.

[EDIT] This of course doesn't work in a multi-threaded environment: Static variables are global (= shared between all threads). What's worse: Due to Java's memory model, a change of the variable in thread 1 might not be visible at any specific point in time to any other threads.

If you need this in a web server, then you can't use static variables anymore. I suggest to create an instance of the class and convert all the static fields into methods. Then you can create this instance in a Filter and put it in the request and configure it correctly.

public class I18nHelper {
    public static I18nHelper get( HttpServletRequest request ) {
        return (HttpServletRequest) request.getAttribute( "I18nHelper" );
    }

    private Locale locale;

    public I18nHelper(Locale locale) {
        this.locale = locale;
    }

    public String msg1() {
        return Translator.get(locale, "MSG1");
    }
}

This approach has another huge advantage: You can pass type-safe arguments!

    public String fileNotFoundMsg( File file ) {
        ... format message with parameter "file" and return it...
    }
like image 120
Aaron Digulla Avatar answered Sep 22 '22 14:09

Aaron Digulla