我的代码中有一堆常量用于我系统的各种可调属性。我将所有这些文件移到中央.properties
文件中。我目前的解决方案是使用一个Properties.java
静态加载.properties
文件并公开各种getter方法,如下所示:
public class Properties {
private static final String FILE_NAME = "myfile.properties";
private static final java.util.Properties props;
static {
InputStream in = Properties.class.getClassLoader().getResourceAsStream(
FILE_NAME);
props = new java.util.Properties();
try {
props.load(in);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String getString(Class<?> cls, String key) {
return props.getProperty(cls.getName() + '.' + key);
}
public static int getInteger(Class<?> cls, String key) {
return Integer.parseInt(getString(cls, key));
}
public static double getDouble(Class<?> cls, String key) {
return Double.parseDouble(getString(cls, key));
}
}
唯一的问题是,对于我从这个文件得到的每个常量,我都有一些样板:
private final static int MY_CONSTANT = Properties.getInteger(
ThisClass.class, "MY_CONSTANT");
我认为我不想使用Spring之类的东西,因为这似乎更像是一个锅炉。我希望使用自定义注释来解决问题。我找到了this tutorial,但我无法理解如何从注释处理中获得我想要的功能。 Java文档甚至没那么有用。不过,这应该是我在编译时应该做的事情。我知道班级和领域的名字。
我的想法是这样的:
@MyAnnotation
private static final int MY_CONSTANT;
任何人都知道我会如何做这个或至少是我想要做的最佳做法?
答案 0 :(得分:2)
首先,你不应该这样做。它很实用,但太过于hacky,如果你想用不同的设置编写测试,你就会遇到问题。而且,没有人会理解它是如何运作的。
注释处理器可能对您无能为力。龙目岛风格的黑客处理器可以。你想做
@MyAnnotation
private static final int MY_CONSTANT;
像
一样工作private final static int MY_CONSTANT =
Properties.getInteger(ThisClass.class, "MY_CONSTANT");
原始表达式没有编译(由于未初始化的最终变量),但它解析得很好,而Lombok可以完成它的工作。那里已经有相关的东西了:
final private
static
实际上,你可以只写
@MyAnnotation
int MY_CONSTANT;
并让你的注释也改变修饰符。我要查看@UtilityClass
的{{3}}和eclipse处理程序,我想你需要的只是生成初始值设定项(因为它全部都是有效的)该死的很复杂)。
我不认为龙目岛本身会很快实现这一点,因为
static
内容都是不可测试的,而且大多数都是错误的样式Properties
,但这可以通过javac 但我想可能会接受一个贡献。
答案 1 :(得分:1)
实际上并不十分清楚为什么以及您希望存档的内容。
正如我正确指出的那样,您希望使用特殊类型的注释自动为某些static final
文件中的properties
常量赋值。不幸的是这是不可能的没有特殊的黑客攻击。注释与此无关。
原因是必须初始化final
个字段并且它是编译器的请求。 java中没有特殊的注释可以提供你想要的语法糖。
但如果你坚持这个,有两种方法:
Extrim方式。使用默认值初始化所有属性字段。然后在某些static
初始化部分中使用this hack使用reflection
机制初始化此值,并通过读取properties
中的值进行编码。
不那么简单的方法:拒绝final
修饰符对属性字段的请求,并仅使用reflection
填充这些字段值。
此外,对于这些方式,是的,您可以使用注释。但您必须解决以下技术问题:
1)查找classpath中所有类中的所有字段,这些字段都使用特殊annotation
进行注释。看着:
Get all of the Classes in the Classpath和Get list of fields with annotation, by using reflection
2)强制您的Properties
课程在应用程序的所有可能输入点初始化。在此类的静态部分中,您将加载属性文件,然后使用带有反射和类加载器的(1)方法,为所有常量赋值。