简体   繁体   English

重新加载java类中的静态字段

[英]Reload static fields in a java class

I have a class in java which has a number of static final strings and one static Locale variable. 我在java中有一个类,它有许多静态最终字符串和一个静态Locale变量。

These Strings are basically keys to a messagebundle which return the translated Strings using the locale. 这些字符串基本上是一个messagebundle的键,它使用语言环境返回翻译的字符串。

ie,

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. 但由于这些是静态变量,因此它们已使用默认语言环境进行初始化,并且对locale变量的更改没有任何影响。

Is there a way to "reload" these strings everytime the locale variable is changed? 每次更改locale变量时,有没有办法“重新加载”这些字符串?

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. 我不想做出明显的改变(使所有字符串非静态并在构造函数/方法中初始化语言环境),因为这个类有很多消息(250+)并且在很多地方使用。

Yes. 是。 While you can't get Java to run the assignments again, you can move the assignments into a method instead: 虽然您无法让Java再次运行分配,但您可以将分配移动到方法中:

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. 之后,您可以使用方法setLocale()来切换区域设置。 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. 更糟糕的是:由于Java的内存模型,线程1中变量的更改可能在任何其他线程的任何特定时间点都不可见。

If you need this in a web server, then you can't use static variables anymore. 如果您在Web服务器中需要它,那么您就不能再使用静态变量了。 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. 然后,您可以在Filter中创建此实例并将其放入请求中并正确配置它。

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...
    }

Instead of creating a local reference in every place that uses this variable, just use the static method itself. 不要在每个使用此变量的地方创建本地引用,只需使用静态方法本身。

Meaning, if you have a method: 意思是,如果你有一个方法:

public void doSomething() {
   if(locale.isSomeLocale()) { // Do something }
}

Just do: 做就是了:

public void doSomething() {
   if(Locale.getDefault().isSomeLocale()) { // Do something }
}

I think that's the cleanest option you can have. 我认为这是你可以拥有的最干净的选择。 If you try to update 200+ local variables, every time the static variable changes, you'll have a terrible mess. 如果您尝试更新200多个局部变量,每次静态变量发生变化时,您都会遇到可怕的混乱。 This way, every point in your code is aligned with the locale you use. 这样,代码中的每个点都与您使用的语言环境保持一致。

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. 但由于这些是静态变量,因此它们已使用默认语言环境进行初始化,并且对语言环境变量的更改没有任何影响。

You can reassign a static variable, unless, it's final. 您可以重新分配静态变量,除非它是最终的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM