实现Hibernate消息插值器时出现Java Generics错误

时间:2010-12-28 13:31:51

标签: java generics

框架:Spring,Hibernate。 O / S:Windows

我正在尝试按照Link的方向实现hibernate的自定义消息插补器。

实现下面的类时,它会给出错误“无法对非静态类型Locale进行静态引用”。

public class ClientLocaleThreadLocal<Locale> {
  private static ThreadLocal tLocal = new ThreadLocal();

  public static void set(Locale locale) {
    tLocal.set(locale);
  }

  public static Locale get() {
    return tLocal.get();
  }

  public static void remove() {
    tLocal.remove();
  } 

}

由于我不太了解泛型,不确定如何&lt;地区&gt;正在使用下面的TimeFilter类以及上面类中定义的目的。

public class TimerFilter implements Filter {
public void destroy() {
}

public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {
    try {
        ClientLocaleThreadLocal.set(req.getLocale());       
        filterChain.doFilter(req, res);
    }finally {
        ClientLocaleThreadLocal.remove();
    }
}
public void init(FilterConfig arg0) throws ServletException {
}

}

请问以下情况可以吗?

  1. 将ClientLocaleThreadLocal中的静态方法/字段更改为非静态方法/字段

  2. 在TimeFilter中,通过实例化新对象来设置语言环境,如下所示。 new ClientLocaleThreadLocal()。set(req.getLocale())

  3. 感谢您的提前帮助

2 个答案:

答案 0 :(得分:1)

public class ClientLocaleThreadLocal<Locale>

使用名为ClientLocaleThreadLocal的类型参数声明泛型类Locale。由于ClientLocaleThreadLocal始终包含Locale,因此此处不需要类型参数。

private static ThreadLocal tLocal = new ThreadLocal();

相反,ThreadLocal是泛型类型,并且具有类型参数,它包含的对象类型。在您的情况下,这是Locale。因此,您的代码应为:

public class ClientLocaleThreadLocal {
    private static ThreadLocal<Locale> tLocal = new ThreadLocal<Locale>();

至于ThreadLocal是什么,请阅读其Javadoc或谷歌的名称。

res.getLocale()是否是“客户端区域设置”是我们无法知道的,因为“客户端区域设置”有点模糊。

答案 1 :(得分:0)

“Locale”是这里的通用参数。这个特殊名称有点令人困惑,因为它与现有的类型名称冲突。

按照惯例,通用参数通常是单字母大写字母,如T,L,I等。

您收到的具体错误消息:

Cannot make a static reference to the non-static type Locale

是因为类级别的通用参数只能用于instance methods不是 static methods。想想这一秒。泛型参数通常在创建类的新实例时提供,但是使用静态方法时,从不存在实例,因此无法引用实际的泛型参数。

E.g。使用您将使用的通用参数:

ClientLocaleThreadLocal<MyLocale> clt = new ClientLocaleThreadLocal<MyLocale>();
clt.set(someMyLocaleInstance);

但是使用静态方法,你只需要调用它:

ClientLocaleThreadLocal.set(someMyLocaleInstance);

如您所见,从未提供过通用参数。

原来的JBoss示例并不完全正确。