Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>(properties);// why wrong?
java.util.Propertiesはの実装でありjava.util.Map、Andjava.util.HashMapのコンストラクタはMap型パラメータを受け取ります。では、なぜ明示的に変換する必要があるのでしょうか。
Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>(properties);// why wrong?
java.util.Propertiesはの実装でありjava.util.Map、Andjava.util.HashMapのコンストラクタはMap型パラメータを受け取ります。では、なぜ明示的に変換する必要があるのでしょうか。
回答:
これは、PropertiesextendsHashtable<Object, Object>(これが実装するMap<Object, Object>)のためです。あなたはそれをに送り込もうとしますMap<String, String>。したがって、互換性はありません。
文字列のプロパティを1つずつマップにフィードする必要があります...
例えば:
for (final String name: properties.stringPropertyNames())
map.put(name, properties.getProperty(name));
これを行う効率的な方法は、次のように一般的なマップにキャストすることです。
Properties props = new Properties();
Map<String, String> map = (Map)props;
これMap<Object, Object>により、が生のマップに変換されます。これは、コンパイラにとって「問題ありません」(警告のみ)。生を取得Mapすると、キャストさMap<String, String>れ、「OK」になります(別の警告)。注釈付きで無視できます@SuppressWarnings({ "unchecked", "rawtypes" })
JVMでは、オブジェクトは実際にはジェネリック型を持たないため、これは機能します。ジェネリック型は、コンパイル時に物事を検証するための単なるトリックです。
一部のキーまたは値が文字列でない場合、ClassCastExceptionエラーが発生します。現在ではProperties実装これは、限り、あなたはスーパーから変更可能なコール・メソッドを使用していないとして、起こることは非常にそうであるHashtable<Object,Object>のProperties。
したがって、Propertiesインスタンスで厄介なことをしない場合は、これが最適な方法です。
Mapますが、目標は少なくとも指定されたコードにインスタンスを作成することなので、これが彼に必要なものだと思いました
あなたはグーグルグアバを使うことができます:
これはどう?
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は仕様によるものであり、それ自体は一般的ではありません。
次のGuavaAPIを使用します: com.google.common.collect.Maps#fromProperties
Properties properties = new Properties();
Map<String, String> map = Maps.fromProperties(properties);
もし、あんたが Propertiesオブジェクトに<String, String>エントリのみが含まれているわかっている、raw型を使用できます。
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> `を拡張します。
これは、HashMapのコンストラクターがMapジェネリック型の引数を必要とし、PropertiesがMapを実装しているためです。
これは機能しますが、警告が表示されます
Properties properties = new Properties();
Map<String, String> map = new HashMap(properties);
Hashtable<Object, Object>文字列ではないものでも、文字列ではないキーでも、好きなものをフィードできます。