Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>(properties);// why wrong?
java.util.Properties
ist eine Implementierung von java.util.Map
. java.util.HashMap
Der Konstruktor von And empfängt einen Map
Typparameter. Warum muss es also explizit konvertiert werden?
Hashtable<Object, Object>
, auch Dinge, die keine Zeichenfolgen sind - sogar Schlüssel, die keine Zeichenfolgen sind.Der effizienteste Weg, dies zu tun, besteht darin, wie folgt auf eine generische Karte zu übertragen:
Dadurch wird a
Map<Object, Object>
in eine unformatierte Map konvertiert , was für den Compiler "ok" ist (nur Warnung). Sobald wir ein RawMap
haben, wird es gewirkt, zuMap<String, String>
dem es auch "ok" sein wird (eine weitere Warnung). Sie können sie mit Anmerkungen ignorieren@SuppressWarnings({ "unchecked", "rawtypes" })
Dies funktioniert, da das Objekt in der JVM keinen generischen Typ hat. Generische Typen sind nur ein Trick, der die Dinge beim Kompilieren überprüft.
Wenn ein Schlüssel oder Wert kein String ist, wird ein
ClassCastException
Fehler ausgegeben. Bei der aktuellenProperties
Implementierung ist dies sehr unwahrscheinlich, solange Sie nicht die veränderlichen Aufrufmethoden von superHashtable<Object,Object>
of verwendenProperties
.Wenn Sie also mit Ihrer Properties-Instanz keine bösen Dinge tun, ist dies der richtige Weg.
quelle
Map
Instanz mit dem angegebenen Code zu haben, also dachte ich, dass er das brauchtSie könnten Google Guavas verwenden:
com.google.common.collect.Maps.fromProperties (Eigenschaften)
quelle
Wie wäre es damit?
Verursacht eine Warnung, funktioniert aber ohne Iterationen.
quelle
Map<Object, Object>
, es ist einMap
Argument ( Rohtyp ). Diese Antwort ist richtig(Map<String, String>) ((Map) properties)
Der Java 8 Weg:
quelle
Properties
GeräteMap<Object, Object>
- nichtMap<String, String>
.Sie versuchen, diesen Konstruktor aufzurufen:
... mit
K
undV
beides alsString
.Aber
Map<Object, Object>
ist nichtMap<? extends String, ? extends String>
... es kann Schlüssel und Werte enthalten, die keine Zeichenfolgen sind.Das würde funktionieren:
... aber es wäre nicht so nützlich für dich.
Grundsätzlich
Properties
hätte niemals eine Unterklasse vonHashTable
... das ist das Problem. Seit v1 ist es immer möglich, Nicht-String-Schlüssel und -Werte zu speichern, obwohl dies gegen die Absicht ist. Wenn stattdessen Komposition verwendet worden wäre, hätte die API nur mit Zeichenfolgenschlüsseln / -werten funktionieren können, und alles wäre gut gewesen.Vielleicht möchten Sie so etwas:
quelle
Properties<String,String> properties = new Properties<String,String>();
. Eigenartig.Properties
selbst ist nicht generisch.Wenn Sie wissen, dass Ihr
Properties
Objekt nur<String, String>
Einträge enthält , können Sie auf einen Rohtyp zurückgreifen:quelle
Ich würde die folgende Guava-API verwenden: com.google.common.collect.Maps # fromProperties
quelle
Das Problem ist, dass
Properties
implementiertMap<Object, Object>
, während derHashMap
Konstruktor a erwartetMap<? extends String, ? extends String>
.Diese Antwort erklärt diese (ziemlich kontraintuitive) Entscheidung. Kurzum: vor Java 5
Properties
implementiertMap
(da es damals keine Generika gab). Dies bedeutete, dass Sie jedesObject
in einProperties
Objekt einfügen konnten. Dies ist noch in der Dokumentation:Um die Kompatibilität damit aufrechtzuerhalten, hatten die Designer keine andere Wahl, als es
Map<Object, Object>
in Java 5 zu erben . Es ist ein unglückliches Ergebnis des Strebens nach vollständiger Abwärtskompatibilität, das neuen Code unnötig kompliziert macht.Wenn Sie in Ihrem
Properties
Objekt immer nur Zeichenfolgeneigenschaften verwenden , sollten Sie in der Lage sein, mit einer ungeprüften Umwandlung in Ihrem Konstruktor davonzukommen:oder ohne Kopien:
quelle
public HashMap(Map<? extends K, ? extends V> m)
. Es erwartet keineMap<String, String>
Map<Object, Object>
kann nicht für ein formales Argument vom Typ `Map <verwendet werden? erweitert String ,? erweitert String> `.Dies liegt nur daran, dass der Konstruktor von HashMap ein Argument vom generischen Map-Typ benötigt und Properties Map implementiert.
Dies wird funktionieren, allerdings mit einer Warnung
quelle
Erste Sache,
In der HashMap-Klasse gibt es keinen solchen Konstruktor, der ein Eigenschaftenobjekt verwendet und Ihnen ein Hashmap-Objekt zurückgibt. Was Sie also tun, ist NICHT korrekt. Sie sollten in der Lage sein, das Objekt von Eigenschaften in eine Hashtabellenreferenz umzuwandeln.
quelle
ich benutze das:
quelle
Sie können dies verwenden:
quelle