Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>(properties);// why wrong?
java.util.Properties是的实现java.util.Map,并且java.util.HashMap的构造函数接收Map类型参数。那么,为什么必须对其进行显式转换?
Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>(properties);// why wrong?
java.util.Properties是的实现java.util.Map,并且java.util.HashMap的构造函数接收Map类型参数。那么,为什么必须对其进行显式转换?
Answers:
这是因为PropertiesextendsHashtable<Object, Object>(又实现了Map<Object, Object>)。您尝试将其输入Map<String, String>。因此,它是不兼容的。
您需要将字符串属性一一输入到地图中。
例如:
for (final String name: properties.stringPropertyNames())
map.put(name, properties.getProperty(name));
做到这一点的有效方法只是将其转换为通用Map,如下所示:
Properties props = new Properties();
Map<String, String> map = (Map)props;
这会将a转换Map<Object, Object>为原始Map,对于编译器来说这是“确定”的(仅警告)。一旦我们有了原始数据Map,它将被转换Map<String, String>为“ ok”(另一个警告)。您可以通过注释忽略它们@SuppressWarnings({ "unchecked", "rawtypes" })
这将起作用,因为在JVM中,该对象实际上并没有泛型类型。泛型类型只是在编译时验证事物的一种技巧。
如果某些键或值不是字符串,则会产生ClassCastException错误。与目前Properties执行这是非常不可能发生的,只要你不使用可变的调用方法从超Hashtable<Object,Object>的Properties。
因此,如果不对您的Properties实例进行任何令人讨厌的事情,这就是方法。
Map至少在给定的代码上有一个实例,所以我认为这就是他所需要的
您可以使用Google Guava的:
这个怎么样?
Map properties = new Properties();
Map<String, String> map = new HashMap<String, String>(properties);
将引起警告,但无需迭代即可工作。
Map<Object, Object>,而是Map参数(原始类型)。这个答案是正确的
(Map<String, String>) ((Map) properties)
Java 8方式:
properties.entrySet().stream().collect(
Collectors.toMap(
e -> e.getKey().toString(),
e -> e.getValue().toString()
)
);
Properties实现Map<Object, Object>-不是Map<String, String>。
您正在尝试调用此构造函数:
public HashMap(Map<? extends K,? extends V> m)
...与K和V都为String。
但这Map<Object, Object>不是Map<? extends String, ? extends String>...它可以包含非字符串键和值。
这将工作:
Map<Object, Object> map = new HashMap<Object, Object>();
...但是它对您没有用。
从根本上讲,这Properties绝对不应该成为HashTable...的子类。从v1开始,它始终能够存储非字符串键和值,尽管这违反了意图。如果成分已经代替,该API可以有只使用字符串键/值,并且一切都会很好。
您可能想要这样的东西:
Map<String, String> map = new HashMap<String, String>();
for (String key : properties.stringPropertyNames()) {
map.put(key, properties.getProperty(key));
}
Properties<String,String> properties = new Properties<String,String>();。奇特。
Properties它本身不是通用的。
我将使用以下Guava API: com.google.common.collect.Maps#fromProperties
Properties properties = new Properties();
Map<String, String> map = Maps.fromProperties(properties);
如果你知道你的Properties对象仅包含<String, String>条目,可以求助于原始类型:
Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>((Map) properties);
问题是Properties实现Map<Object, Object>,而HashMap构造函数期望一个Map<? extends String, ? extends String>。
这个答案解释了这个(相当违反直觉的)决定。简而言之:在Java 5之前Properties实现Map(因为那时没有泛型)。这意味着你可以把任何 Object一个Properties对象。这仍然是文档:
由于
Properties继承自Hashtable,putandputAll方法可以应用于Properties对象。不鼓励使用它们,因为它们允许调用方插入键或值不是Strings的条目。setProperty应该改用该方法。
为了保持这种兼容性,设计人员别无选择,只能使其Map<Object, Object>在Java 5中继承。这是努力实现向后兼容性的不幸结果,这种兼容性使不必要的新代码复杂化。
如果只在Properties对象中使用字符串属性,则应该能够在构造函数中使用未经检查的强制转换:
Map<String, String> map = new HashMap<String, String>( (Map<String, String>) properties);
或无任何副本:
Map<String, String> map = (Map<String, String>) properties;
public HashMap(Map<? extends K, ? extends V> m)。没想到Map<String, String>
Map<Object, Object>不能用于Map <?类型的形式参数。扩展String,?扩展String>`。
这仅仅是因为HashMap的构造函数需要一个Map泛型类型的arg,并且Properties实现Map。
这将起作用,尽管有警告
Properties properties = new Properties();
Map<String, String> map = new HashMap(properties);
第一件事
属性类基于Hashtable而不是Hashmap。属性类基本上扩展了Hashtable
HashMap类中没有此类构造函数,该构造函数接受属性对象并返回一个hashmap对象。所以你在做什么是不正确的。您应该能够将属性的对象转换为哈希表引用。
Hashtable<Object, Object>,甚至可以输入非字符串的内容,甚至可以输入非字符串的键。