繁体   English   中英

有什么办法可以在编译时为Java定义一个常量值

[英]Is there any way to define a constant value to Java at compile time

当我过去用C / C ++编写库时,我习惯于拥有一种返回编译日期/时间的方法。 它始终是编译到库中的,因此可以区分库的内部版本。 我通过在代码中返回#define来获得此信息:

C ++:

#ifdef _BuildDateTime_
   char* SomeClass::getBuildDateTime() {
      return _BuildDateTime_;
   }
#else
   char* SomeClass::getBuildDateTime() {
      return "Undefined";
   }
#endif

然后在编译时,我在构建脚本中有一个'-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();
}

在我看来,这是一种黑客行为,可能会被JAR 外部但在类路径上具有类似名称的文件的人绕开/破坏。

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

编辑

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

我个人偏爱使用serg10建议的使用JAR文件中的日期。

我赞成基于标准的方法。 将您的版本信息(以及其他有用的发布者资料,例如内部版本号,Subversion修订号,作者,公司详细信息等)放入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();

对我来说,这感觉更像是Java标准方法,因此对于后来的代码维护人员来说,可能会变得更加容易。

我记得在一个开源项目中看到过类似的事情:

class Version... {
  public static String tstamp() {
    return "@BUILDTIME@";
  }
}

在模板文件中。 使用Ant的过滤副本,您可以为该宏赋予一个值:

<copy src="templatefile" dst="Version.java" filtering="true">
    <filter token="BUILDTIME" value="${build.tstamp}" />
</copy>

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

AFAIK没有办法用javac做到这一点。 使用Ant可以轻松做到这一点-我将创建一个名为BuildTimestamp.java的一流对象,并在编译时通过Ant目标生成该文件。

这是一个有用的Ant类型

除非您想通过C / C ++预处理程序(这是BIG NO-NO)运行Java源代码,否则请使用jar方法。 还有其他方法可以从jar中获取正确的资源,以确保有人没有在类路径上放置重复的资源。 您也可以考虑为此使用Jar清单。 我的项目完全使用清单来完成您要执行的操作(带有生成日期,修订,作者等)。

您将要使用此:

Enumeration<URL> resources = Thread.currentThread().getContextClassLoader().getResources("META-INF/MANIFEST.MF");

这将为您提供类路径上的所有清单。 您可以通过解析URL找出它们可以使用的jar。

就我个人而言,我会在运行时加载的jar中查找单独的属性文件...类加载器具有定义的文件搜索顺序-我不记得它是如何工作的,但是我不知道认为在类路径上某处具有相同名称的另一个文件很可能会引起问题。

但是您可以执行的另一种方法是,在编译它们之前使用Ant将.java文件复制到另一个目录中,并在适当时过滤字符串常量。 您可以使用类似:

public String getBuildDateTime() {
    return "@BUILD_DATE_TIME@";
}

然后在您的Ant文件中编写一个过滤器,以将其替换为build属性。

指示清单库版本的更Java风格的方法可能是,如清单文档中所述,在JAR清单中添加版本号。

我从同事那里得到的一个建议是获取ant文件,以在类路径上创建一个文件,并将其打包到JAR中,并由该方法读取。 ...据我所知,这是一种黑客行为,可能会被JAR外部但在类路径上具有类似名称的文件的人绕开/破坏。

我不确定让Ant生成文件是否是骇人听闻的骇人听闻的破解,即使它完全是骇客。 为什么不生成属性文件并使用java.util.Properties处理它?

暂无
暂无

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

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