有没有办法在编译时为Java定义一个常量值

GKe*_*lly 12 c c++ java

当我以前用C/C++编写库时,我养成了使用方法返回编译日期/时间的习惯.这总是被编译到库中,因此可以区分库的构建.我通过在代码中返回#define得到了这个:

C++:

#ifdef _BuildDateTime_
   char* SomeClass::getBuildDateTime() {
      return _BuildDateTime_;
   }
#else
   char* SomeClass::getBuildDateTime() {
      return "Undefined";
   }
#endif
Run Code Online (Sandbox Code Playgroud)

然后在编译时我有一个'-D_BuildDateTime_ =Date在构建脚本中 '.

有没有办法在Java中实现这个或类似的,而无需记住手动编辑任何文件或分发任何单独的文件.

我从同事那里得到的一个建议就是让ant文件在类路径上创建一个文件并将其打包到JAR中并让它通过该方法读取.

类似的东西(假设创建的文件名为'DateTime.dat'):

// I know Exceptions and proper open/closing 
// of the file are not done. This is just 
// to explain the point!
String getBuildDateTime() {
    return new BufferedReader(getClass()
            .getResourceAsStream("DateTime.dat")).readLine();
}
Run Code Online (Sandbox Code Playgroud)

在我看来,这是一个黑客,可以被外面有类似命名文件的人规避/破坏在JAR,但是在类路径上.

无论如何,我的问题是在编译时是否有任何方法将一个常量注入一个类

编辑

我考虑在JAR中使用外部生成的文件的原因是因为这一个库并将嵌入到客户端应用程序中.这些客户端应用程序可能会定义自己的类加载器,这意味着我不能依赖标准的JVM类加载规则.

我个人的偏好是使用serg10建议的JAR文件中的日期.

ser*_*g10 15

我赞成基于标准的方法. 将您的版本信息(以及其他有用的发布者内容,例如内部版本号,颠覆版本号,作者,公司详细信息等)放入jar的清单文件中.

这是一个记录良好且易于理解的Java规范. 存在用于创建清单文件的强大工具支持(例如,核心Ant任务maven jar插件).这些可以帮助自动设置一些属性 - 我有maven配置为在构建时将jar的maven版本号,Subversion修订版和时间戳放入清单中.

您可以使用标准的java api调用在运行时读取清单的内容 - 类似于:

import java.util.jar.*;

...

JarFile myJar = new JarFile("nameOfJar.jar");    // various constructors available
Manifest manifest = myJar.getManifest();
Map<String,Attributes> manifestContents = manifest.getAttributes();
Run Code Online (Sandbox Code Playgroud)

对我而言,这感觉就像是一种更加Java标准的方法,因此后续代码维护者可能会更容易理解.


Kar*_*arl 11

我记得在开源项目中看到类似的东西:

class Version... {
  public static String tstamp() {
    return "@BUILDTIME@";
  }
}
Run Code Online (Sandbox Code Playgroud)

在模板文件中.使用Ant的过滤副本,您可以为此宏指定一个值:

<copy src="templatefile" dst="Version.java" filtering="true">
    <filter token="BUILDTIME" value="${build.tstamp}" />
</copy>
Run Code Online (Sandbox Code Playgroud)

在编译步骤之前,使用它在构建过程中创建Version.java源文件.