Java 如何在编译时使用属性文件创建动态接口?

Java 如何在编译时使用属性文件创建动态接口?,java,properties-file,Java,Properties File,这里的问题是,我们使用的属性文件有一个非常巨大的名称作为密钥,我们大多数人都会遇到不正确的密钥命名问题。因此,它让我思考是否有一种方法可以基于属性文件生成以下接口。我们对属性文件所做的每一次更改都将自动调整属性界面。还是有其他解决办法 属性文件 A=Apple B=Bannana C=Cherry 应该生成以下接口 interface Properties{ public static final String A = "A" // keys public static final Strin

这里的问题是,我们使用的属性文件有一个非常巨大的名称作为密钥,我们大多数人都会遇到不正确的密钥命名问题。因此,它让我思考是否有一种方法可以基于属性文件生成以下接口。我们对属性文件所做的每一次更改都将自动调整属性界面。还是有其他解决办法

属性文件

A=Apple
B=Bannana
C=Cherry
应该生成以下接口

interface Properties{
public static final String A = "A" // keys
public static final String B = "B"; 
public static final String C = "C"; 

}
所以在我的应用程序代码中

String a_value = PROP.getString(Properties.A);

关于编程有一条古老的规则,不仅仅是关于它,如果某些东西看起来很漂亮,那么它很可能是正确的方法

在我看来,这种方法看起来不太好

第一件事:

不要在接口中声明常量。它违反了内陷法。请检查这篇文章:

第二件事:

使用前缀来命名某些特殊属性的部分,比如:
key\uu

当您加载属性文件时,迭代键并提取名称以
key\uu
开头的键,并按照您计划在问题中使用这些常量的方式使用这些键的值


更新

假设,我们在编译过程中使用ApacheAnt脚本生成一个巨大的属性文件

例如,让我们看看属性文件(
myapp.properties
)如下所示:

key_A = Apple
key_B = Banana
key_C = Cherry
anotherPropertyKey1 = blablabla1
anotherPropertyKey2 = blablabla2
我们要处理的特殊属性的键名以
key\uu
前缀开头

因此,我们编写以下代码(请注意,它没有经过优化,只是概念证明):

它是具有特殊键名的返回数组的字符串表示形式


根据需要更改此代码。

我不会从属性生成类或接口,因为您将失去以下功能:

  • 记录这些属性,因为它们将由java元素+javadocs表示
  • 在代码中引用这些属性,因为它们将是旧的java常量,编译器将完全了解它们。重构它们也是可能的,而自动命名是不可能的
您还可以使用枚举,或者创建一些特殊的
属性
类,将名称作为唯一字段和最终字段。然后,您只需要一个
get
方法,该方法将采用
Properties
Map
或其他方法

对于您的请求,您可以使用执行代码

您只需创建一个可以读取属性文件的main,对于每个键:

  • 将密钥转换为有效的java标识符(您可以使用和将无效字符替换为
  • 使用普通的旧Java编写您的类/接口/任何您喜欢的东西(不要忘记转义,以获得最终的双引号或反斜杠!)
因为它是构建的一部分,比如在构建依赖于这些常量的其他类之前,我建议您创建一个特定的maven项目来隔离这些构建


不过,我真的不这么做,并使用POJO加载任何需要(CDI、施普灵河、静态初始化等)。

看起来像是在学习Maven。您是否认为更改属性文件会在应用程序中创建编译错误?我个人会生成一次属性界面,然后手工维护它。也许我会使用枚举而不是接口。您可以在编译时修改属性文件,例如,使用ApacheAnt。在这种情况下,您不需要更改代码。只需根据需要修改属性文件。您的代码将使用描述的方法提取所有属性。答案不清楚。什么是迭代键和提取键?在
Properties
类中,有一个方法。调用它以获取属性名称。遍历此枚举以获取属性名称并对其进行处理。要检查属性名是否以
键开头(例如),请使用method.ohh,这是获取属性的常用例程,不是吗?。在这种情况下,属性键极易出错。所以我们希望它被生成到一个接口字段,这样我们就不会对硬编码键产生任何错误。
package propertiestest;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;


public class PropertiesTest {

  public static void main(String[] args) throws IOException {
       final String PROPERTIES_FILENAME = "myapp.properties";      

       SpecialPropertyKeysStore spkStore = 
                            new SpecialPropertyKeysStore(PROPERTIES_FILENAME);

       System.out.println(Arrays.toString(spkStore.getKeysArray()));

   }
}


class SpecialPropertyKeysStore {

    private final Set<String> keys;

    public SpecialPropertyKeysStore(String propertiesFileName) 
                                    throws FileNotFoundException, IOException {


        // prefix of name of a special property key
        final String KEY_PREFIX = "key_";        

    Properties propertiesHandler = new Properties();
        keys = new HashSet<>();

    try (InputStream input = new FileInputStream(propertiesFileName)) {

            propertiesHandler.load(input);

            Enumeration<?> enumeration = propertiesHandler.propertyNames();
            while (enumeration.hasMoreElements()) {
                String key = (String) enumeration.nextElement();
                if (key.startsWith(KEY_PREFIX)) {
                    keys.add(key);
                }
            }
    }        
    }

    public boolean isKeyPresent(String keyName) {
        return keys.contains(keyName);
    }

    public String[] getKeysArray() {
        String[] strTypeParam = new String[0];

        return keys.toArray(strTypeParam);
    }
}
[key_C, key_B, key_A]