In meiner Kontextdatei für die Frühlingsanwendung habe ich Folgendes:
<util:map id="someMap" map-class="java.util.HashMap" key-type="java.lang.String" value-type="java.lang.String">
<entry key="some_key" value="some value" />
<entry key="some_key_2" value="some value" />
</util:map>
In der Java-Klasse sieht die Implementierung folgendermaßen aus:
private Map<String, String> someMap = new HashMap<String, String>();
someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");
In Eclipse sehe ich eine Warnung, die besagt:
Typensicherheit: Deaktivierte Umwandlung von Objekt in HashMap
Was habe ich falsch gemacht? Wie löse ich das Problem?
java
spring
type-safety
unchecked
DragonBorn
quelle
quelle
Antworten:
Zunächst einmal verschwenden Sie mit dem neuen
HashMap
Erstellungsaufruf Speicherplatz . In Ihrer zweiten Zeile wird der Verweis auf diese erstellte Hashmap vollständig ignoriert, sodass sie dem Garbage Collector zur Verfügung steht. Also, tu das nicht, benutze:Zweitens beschwert sich der Compiler, dass Sie das Objekt in a umwandeln
HashMap
umwandeln, ohne zu überprüfen, ob es a istHashMap
. Aber selbst wenn Sie tun würden:Sie würden diese Warnung wahrscheinlich immer noch erhalten. Das Problem ist,
getBean
kehrt zurückObject
, so dass es unbekannt ist, um welchen Typ es sich handelt. EineHashMap
direkte Konvertierung würde das Problem im zweiten Fall nicht verursachen (und möglicherweise würde es im ersten Fall keine Warnung geben, ich bin mir nicht sicher, wie pedantisch der Java-Compiler mit Warnungen für Java 5 ist). Sie konvertieren es jedoch in aHashMap<String, String>
.HashMaps sind wirklich Maps, die ein Objekt als Schlüssel nehmen und ein Objekt als Wert haben.
HashMap<Object, Object>
wenn Sie so wollen. Daher gibt es keine Garantie dafür, dass Ihre Bean, wenn Sie sie erhalten, als dargestellt werden kann,HashMap<String, String>
weil dies möglich ist,HashMap<Date, Calendar>
da die zurückgegebene nicht generische Darstellung beliebige Objekte enthalten kann.Wenn der Code kompiliert wird und Sie
String value = map.get("thisString");
fehlerfrei ausführen können, machen Sie sich keine Sorgen über diese Warnung. Wenn die Zuordnung jedoch nicht vollständig aus Zeichenfolgenschlüsseln zu Zeichenfolgenwerten besteht, erhalten SieClassCastException
zur Laufzeit eine, da die Generika dies in diesem Fall nicht blockieren können.quelle
Das Problem ist, dass eine Umwandlung eine Laufzeitprüfung ist - aber aufgrund der Typlöschung gibt es zur Laufzeit tatsächlich keinen Unterschied zwischen a
HashMap<String,String>
undHashMap<Foo,Bar>
für andereFoo
undBar
.Benutze
@SuppressWarnings("unchecked")
und halte deine Nase. Oh, und Kampagne für reifizierte Generika in Java :)quelle
Wie aus den obigen Meldungen hervorgeht, kann die Liste nicht zwischen a
List<Object>
und aList<String>
oder unterschieden werdenList<Integer>
.Ich habe diese Fehlermeldung für ein ähnliches Problem gelöst:
mit den folgenden:
Erläuterung: Bei der ersten Typkonvertierung wird überprüft, ob es sich bei dem Objekt um eine Liste handelt, ohne dass die darin enthaltenen Typen berücksichtigt werden müssen (da die internen Typen auf Listenebene nicht überprüft werden können). Die zweite Konvertierung ist jetzt erforderlich, da der Compiler nur weiß, dass die Liste bestimmte Objekte enthält. Dadurch wird der Typ jedes Objekts in der Liste beim Zugriff überprüft.
quelle
Eine Warnung ist genau das. Eine Warnung. Manchmal sind Warnungen irrelevant, manchmal nicht. Sie werden verwendet, um Ihre Aufmerksamkeit auf etwas zu lenken, von dem der Compiler glaubt, dass es ein Problem sein könnte, aber möglicherweise nicht.
Im Fall von Casts wird in diesem Fall immer eine Warnung ausgegeben. Wenn Sie absolut sicher sind, dass eine bestimmte Besetzung sicher ist, sollten Sie eine Anmerkung wie diese (ich bin mir der Syntax nicht sicher) kurz vor der Zeile hinzufügen:
quelle
Sie erhalten diese Nachricht, weil getBean eine Objektreferenz zurückgibt und Sie sie in den richtigen Typ umwandeln. Java 1.5 gibt Ihnen eine Warnung. Das ist die Natur der Verwendung von Java 1.5 oder besser mit Code, der so funktioniert. Frühling hat die typsichere Version
auf seiner Aufgabenliste.
quelle
Wenn Sie die Warnungen wirklich entfernen möchten, können Sie eine Klasse erstellen, die von der generischen Klasse ausgeht.
Zum Beispiel, wenn Sie versuchen, zu verwenden
Sie können eine neue Klasse wie diese erstellen
Dann, wenn Sie verwenden
Der Compiler kennt die (nicht mehr generischen) Typen und es wird keine Warnung ausgegeben. Dies ist möglicherweise nicht immer die perfekte Lösung. Einige argumentieren möglicherweise, dass diese Art der Niederlage den Zweck generischer Klassen zunichte macht. Sie verwenden jedoch immer noch denselben Code aus der generischen Klasse. Sie deklarieren lediglich zur Kompilierungszeit, welcher Typ Sie möchten verwenden.
quelle
Die Lösung, um die ungeprüfte Warnung zu vermeiden:
quelle
Eine andere Lösung, wenn Sie feststellen, dass Sie dasselbe Objekt häufig umwandeln und Ihren Code nicht verunreinigen
@SupressWarnings("unchecked")
möchten, besteht darin, eine Methode mit der Anmerkung zu erstellen. Auf diese Weise zentralisieren Sie die Besetzung und reduzieren hoffentlich die Fehlerwahrscheinlichkeit.quelle
Der folgende Code verursacht Typensicherheitswarnung
Map<String, Object> myInput = (Map<String, Object>) myRequest.get();
Erstellen Sie ein neues Kartenobjekt, ohne die Parameter zu erwähnen, da der in der Liste enthaltene Objekttyp nicht überprüft wird.
Schritt 1: Erstellen Sie eine neue temporäre Karte
Map<?, ?> tempMap = (Map<?, ?>) myRequest.get();
Schritt 2: Instanziieren Sie die Hauptkarte
Schritt 3: Iterieren Sie die temporäre Karte und legen Sie die Werte in der Hauptkarte fest
quelle
Hier :
Map<String,String> someMap = (Map<String,String>)getApplicationContext().getBean("someMap");
Sie verwenden eine Legacy-Methode, die wir im Allgemeinen nicht verwenden möchten, da diese Folgendes zurückgibt
Object
:Die Methode, um eine Bohne aus einer Bohnenfabrik zu erhalten (für Singleton) / zu erstellen (für einen Prototyp), ist:
Verwenden Sie es wie:
wird kompiliert, aber immer noch mit einer ungeprüften Konvertierungswarnung, da nicht alle
Map
Objekte unbedingt sindMap<String, String>
.Aber
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
reicht jedoch in generischen Bean-Klassen wie generischen Sammlungen nicht aus, da hierfür mehr als eine Klasse als Parameter angegeben werden muss: der Sammlungstyp und seine generischen Typen.In einem solchen Szenario und im Allgemeinen besteht ein besserer Ansatz darin, nicht direkt zu verwenden
BeanFactory
Methoden , sondern das Framework die Bean injizieren zu lassen.Die Bohnendeklaration:
Die Bohneninjektion:
quelle