Java 常数和注释

Java 常数和注释,java,Java,这可能是一个愚蠢的问题,因为我对java缺乏了解,但我有以下代码: @Stateless @WebService public class MLHRequesterBean implements MLHRequesterBeanRemote { private final static String sel = "MLHRequesterPU" + (isProduction()? " " : "-dev"); public static boolean isProducti

这可能是一个愚蠢的问题,因为我对java缺乏了解,但我有以下代码:

@Stateless
@WebService
public class MLHRequesterBean implements MLHRequesterBeanRemote {

    private final static String sel = "MLHRequesterPU" + (isProduction()? " " : "-dev");

    public static boolean isProduction(){
        try {
           if (Inet4Address.getLocalHost().getHostName().equalsIgnoreCase("ironman")) {
                return true;
            }
        } catch (UnknownHostException ex) {}
        return false;
    }

    @PersistenceContext(unitName=sel)
    ...
为什么sel不被视为常数?我们有测试服务器和生产服务器,每个服务器都应该写入不同的数据库。我如何克服这个问题

这就是错误:

C:\projects\workspace\MLHRequester\MLHRequester ejb\src\java\mlh\MLHRequesterBean.java:33:属性值必须为常量 @PersistenceContext(unitName=sel)
1 error

sel是最终静态,但其值在首次加载此类时进行评估。
@注释是在编译时计算的,因此会出现错误


最好在构建过程中执行宏/替换预处理步骤来生成正确的值(可能是基于.properties文件)

常量是可以在编译时完全解析的值,sel变量不能,因为它需要查询本地主机名,因此在运行时之前无法对其求值。

sel不是JLS中定义的常量,因为它不能在编译时完全解析。注释需要在编译时完全解析,因为它们被烘焙到类定义中——它们不是运行时属性(这是它们的缺点)


要在运行时通过EJB动态获得此行为,您必须使用EntityManagerFactory。

我必须研究在解决注释之前是否执行静态初始值设定项块(即解决实际问题),但您应该使用静态块来处理以下事项:

public class MLHRequesterBean implements MLHRequesterBeanRemote 
{
    private final static String sel;
    static
    {
        String suffix = (Inet4Address.getLocalHost().getHostName().equalsIgnoreCase("ironman")) ? " " : "dev";
        sel = "MLHRequesterPU".concat(suffix);
    }
}