【问题标题】:How does the java.util.Properties work when getting a key? [closed]java.util.Properties 在获取密钥时如何工作? [关闭]
【发布时间】:2017-12-18 14:19:26
【问题描述】:

java.util.Properties 实例的属性是可直接寻址的,例如prop.myKey 返回与 myKey 关联的值。我想复制这种行为。

它是如何工作的?

在 Java 中没有像 Python 的魔术方法 AFAIK 一样。

具体来说,我想创建类似Properties 的东西,但它支持列表值。我不想添加额外的依赖项(例如commons),所以只想要最简单的添加方式。我见过this answer 并正在尝试将其添加到自定义属性类(我可能是属性的子类,我不介意任何一种方式)。

【问题讨论】:

  • 不确定您的问题是否正确,但您想公开密钥吗?
  • 是的。它将从配置文件中加载。
  • 正如文档所说,Properties 扩展 Hashtable<Object,Object>。如果你想复制行为,你可以使用Map<String, List<YourClass>
  • @QBrute 不,因为并非所有值都是列表。
  • 只有prop.getProperty("myKey") - 没有对象映射。 JAXB 可以将 XML 映射到 java 对象。

标签: java


【解决方案1】:

您所要求的在 Java 中是不可能实现的。

在 Java 中,类的“布局”在编译时固定

当您希望对象允许“x.y”访问字段时,您的 java 源代码必须在 X 类中包含 y 的声明。

您不能动态地将字段添加到类中。

Java的方式是有一个List类型的字段,简单的调用比如

someList.get(1);

或类似的东西。 Python 是一个解释器,它允许您在运行时执行这种“魔法”。 Java 是静态类型的,但不是。

作为记录,正如之前提到的 groovy:groovy 实际上是一种“完全动态”的语言(例如,参见 here)。但问题是:一旦您开始利用实际使用动态“最后一点”的特性——那么唯一的方法就是在 JVM 中实际运行 groovy 解释器。这需要相当多的运行时成本(也可以“编译”groovy 脚本——这会带来更好的性能,但另一方面允许更少的“动态”)。

【讨论】:

  • 我的错。它不是 java 的时髦。似乎它也很神奇:-(
  • @jbrown 当您想要 groovy 的“完全动态”魔力时,可以通过在 JVM 中运行它们的 解释器 来实现。这当然是可能的,但会大大降低执行速度。
  • 只要说“确保你没有使用 groovy”:-D
  • @jbrown 每个工具都有它的位置。永远不要把话说绝了。但我仍然增强了我的答案;-)
【解决方案2】:

你确定 Properties 没有给你想要的行为吗?

Properties a = new Properties();
List<String> listProperty = new ArrayList<>();
listProperty.add("value");
a.put("key", listProperty);
System.out.println(a.get("key"));

[值]

【讨论】:

  • 我正在从配置文件中加载它。所以我需要实现一个方法将配置文件中的字符串值转换为列表。请参阅我上面链接的答案,了解我正在尝试做的事情。
  • 配置文件中的字符串值会有什么格式?逗号分隔列表?
  • 没有。 key.1=x key.2=y 与链接答案中的完全一样。
  • 链接的问题似乎略有不同,因为它指出属性的格式... A=APPLE A=ALPHABET A=ANT B=BAT B=BALL B=BUS 无论如何我认为您正在寻找的解决方案将是一个自定义类,它扩展了 Properties 并覆盖了 load 方法来处理特定的用例。或者完全自定义的属性类
【解决方案3】:

Java 不允许您直接通过键访问属性,就好像它们是 java.util.Properties 类的公共实例字段一样(groovy 或 python 的方式使其变得简单)。

你需要调用getProperty方法:

prop.getProperty("myKey"); //Returns a string

或者,你可以调用get方法:

prop.get("myKey"); //this one returns a string but the return type is Object

使用属性实例,您可以检索键集:

prop.keySet(); // returns a set of strings used as keys

【讨论】:

  • 那么 Properties 类是如何工作的呢?它扩展了 HashTable,但可以直接调用 propInstance.myKey
  • @jbrown 不,你不能那样做。您不能直接访问属性键或使用括号表示法
【解决方案4】:

只需使用通常的properties format。您可以使用自己选择的分隔符存储值列表:

names: Stan,Kyle,Cartman,Kenny,Butters

而且代码可以简单地拆分它们:

List<String> names = Arrays.asList(properties.getProperty("names").split(","));

如果您的值可能包含逗号,请使用不同的分隔符,例如换行符:

names: Stan\nKyle\nCartman\nKenny\nButters

代码:

List<String> names = Arrays.asList(properties.getProperty("names").split("\n"));

属性格式允许延续到多行。您可以使用它来增强可读性:

names: \
    Stan\n\
    Kyle\n\
    Cartman\n\
    Kenny\n\
    Butters

【讨论】:

  • 我做不到。值太复杂,可以包含逗号。我需要例如myVal.1=x(新行)myVal.2=y 都可以在 myVal 下访问
  • 不能用换行符作为分隔符吗?如果不是这样,还有许多其他选择,包括字面上用作字段分隔符的控制字符。
  • 不,我需要为每个列表项设置单独的键。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-20
  • 1970-01-01
  • 2018-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多