将对象放入java.util.Properties

时间:2015-05-21 18:25:49

标签: java

我试图理解为什么java.util.Properties以这种方式实现。它有两个接口:getProperty / setProperty只接受字符串,put / get接受任何对象作为值。这两个接口看起来是重叠的,因此可以使用getProperty()检索添加了put()的字符串。

这种奇怪的混合接口似乎存在一些问题。放置一个覆盖字符串属性的对象具有清除字符串值的副作用,产生null作为getProperty结果。添加整数或其他具有简单字符串转换的值可能会被误解为属性值(但作为属性,它总是为空)。

我的问题是:这有真正的,实际的原因吗?或者,我怀疑这是一个半生不熟的实施?

7 个答案:

答案 0 :(得分:14)

Joshua BlochEffective Java

中明确提到了这一点
  

[来自第4章]在Properties的情况下,设计者希望只允许字符串作为键和值,但直接访问基础Hashtable允许这个不变量被违反了。违反此不变量后,将无法再使用Properties API的其他部分(loadstore)。当发现这个问题时,纠正它为时已晚,因为客户端依赖于使用非字符串键和值。

该文本是在使用组合而不是继承的上下文中。他基本上使用它作为何时应该使用组合而不是继承的示例。如果Properties包裹Map而不是扩展一个,则可以强制使用String作为键和值的不变。

所以答案是:这是一种疏忽。

答案 1 :(得分:6)

putget的访问是PropertiesHashtable的扩展的结果,不应使用这两种方法(但不能从实现中隐藏由于他们在超类中的公共访问权限。)

Javadocs有一个很好的说明为什么你不应该使用这些方法,而应该只使用字符串:

  

由于Properties继承自Hashtable,因此putputAll方法可应用于Properties对象。强烈建议不要使用它们,因为它们允许调用者插入其键或值不是Strings的条目。应该使用setProperty方法。如果在包含非store键或值的“受损”save对象上调用PropertiesString方法,则调用将失败。同样,如果在包含非propertyNames密钥的“受损”list对象上调用,则对PropertiesString方法的调用将失败。

正如@yshavit指出的那样,Properties扩展Hashtable<String, String>比使用两个对象的散列表更有意义,但这可能是为了保持向后兼容性而做出的决定,因为任何程序都使用任何非String对象的get / put都会被这样的更改破坏。

答案 2 :(得分:2)

官方文件说

  

因为Properties继承自Hashtable,所以put和putAll方法可以应用于Properties对象。强烈建议不要使用它们,因为它们允许调用者插入其键或值不是字符串的条目。应该使用setProperty方法。如果在包含非String键或值的“受损”Properties对象上调用store或save方法,则调用将失败。同样,如果在包含非String键的“受损”Properties对象上调用propertyNames或list方法,则调用将失败。

http://docs.oracle.com/javase/8/docs/api/java/util/Properties.html

答案 3 :(得分:1)

来自Java Docs

  

因为Properties继承自Hashtable,put和putAll方法   可以应用于Properties对象。它们的用途很强烈   不鼓励,因为他们允许调用者插入其键或键的条目   值不是字符串。应该使用setProperty方法。   如果在“受损”属性上调用存储或保存方法   包含非String键或值的对象,调用将失败。   同样,如果调用propertyNames或list方法将失败   它在包含a的“受损”属性对象上调用   非字符串键。

答案 4 :(得分:0)

Properties扩展了Hashtable,因此您可以在任何可以使用Properties的地方使用Hashtable

Hashtable类是get()put()函数的来源。

答案 5 :(得分:0)

put(key, value)get(key)是在当天Properties延长Hashtable的可疑决定的遗留问题。这种行为不会发生变化,因为它会破坏向后兼容性,但任何一半体面的样式指南,包括API文档本身,都会建议永远不要使用这些方法。

答案 6 :(得分:0)

正如其他人所说的那样,你只能将它用于Strings。有一些方法可以将对象序列化为字符串并检索它,但显然它并不意味着它。我知道它真的很烦人,因为它是最接近保存和检索应用数据的跨平台方式。据我所知,尽管大多数操作系统都有appdata目录,但在用户隐藏的文件夹中除了字符串之外没有其他正式方法可以保存。