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

时间:2014-02-26 10:22:26

标签: java static

我在java中有一个类,它有许多静态最终字符串和一个静态Locale变量。

这些字符串基本上是一个messagebundle的键,它使用语言环境返回翻译的字符串。

即,

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

此语言环境变量根据浏览器语言环境在运行时设置。 但由于这些是静态变量,因此它们已使用默认语言环境进行初始化,并且对locale变量的更改没有任何影响。

有没有办法重新加载"每次更改locale变量时都会显示这些字符串吗?

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

3 个答案:

答案 0 :(得分:6)

是。虽然您无法让Java再次运行分配,但您可以将分配转移到方法中:

public static String MSG1;

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

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

之后,您可以使用方法setLocale()切换区域设置。第一次加载类时,最后使用静态初始化程序块设置语言环境。

[编辑] 这当然不适用于多线程环境:静态变量是全局的(=所有线程之间共享)。更糟糕的是:由于Java的内存模型,线程1中变量的更改可能在任何特定时间点对任何其他线程都不可见。

如果您需要在Web服务器中使用此功能,则不能再使用静态变量。我建议创建一个类的实例,并将所有静态字段转换为方法。然后,您可以在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");
    }
}

这种方法还有另一个巨大优势:你可以传递类型安全的参数!

    public String fileNotFoundMsg( File file ) {
        ... format message with parameter "file" and return it...
    }

答案 1 :(得分:3)

不要在每个使用此变量的地方创建本地引用,只需使用静态方法本身。

意思是,如果你有方法:

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

只是做:

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

我认为这是你可以拥有的最干净的选择。如果您尝试更新200多个局部变量,每次静态变量发生变化时,您都会遇到可怕的混乱。这样,代码中的每个点都与您使用的语言环境保持一致。

答案 2 :(得分:2)

  

但由于这些是静态变量,因此它们已经初始化   使用默认语言环境并且对语言环境变量的更改不会   有任何影响。

您可以重新分配静态变量,除非它是最终的。