Frage

Ich habe diese Funktion implementiert:

 static <X,Y> Y castOrNull(X obj) {
  try {
   return (Y)obj;
  }
  catch(ClassCastException e) {
   return null;
  }
 }

Das gibt mir die Compiler-Warnung:

Type safety: Unchecked cast from X to Y

Was ich nicht genau verstehen. Ist das nicht der try/catch, die ich hier einen Scheck es tue? Kann ich die Warnung ignorieren?

Wird meine Funktion wie erwartet funktionieren oder nicht? Wie würde ich es richtig umsetzen?

ich auch mit einem obj instanceof Y Check versucht, aber das funktioniert nicht wegen der Art und Weise Java Griff Generika.

Btw., Scheint diese Funktion sehr nützlich für mich (zu einem anderen Code sauberer zu machen). Ich frage mich, ob eine solche Funktion bereits in Java existieren können?


Ein Beispiel, wo ich will, es zu benutzen:

    void removeEmptyRawStrings() {
        for(Iterator<Entity> e = entities.iterator(); e.hasNext();) {
            RawString s = castOrNull(e.next());
            if(s != null && s.content.isEmpty()) e.remove();
        }
    }

Ich habe Fälle wie diese sehr oft in meinem Code. Und ich denke, das ist besser lesbar und einfacher als alles andere. Aber bitte geben Sie mir einen besseren Vorschlag, wenn Sie welche haben, wie diesen Code zu machen noch einfacher.

War es hilfreich?

Lösung

So ist das Problem hier ist, dass die generische Parameter Y wenn für dynamische Gießen verwendet wird, wie Object behandelt. Es wird nie eine CCE werfen. Sie erhalten einen CCE geworfen in der Aufruf Methode, wie Sie statische Typsicherheit gebrochen haben.

Auch X ist völlig sinnlos hier:

Mit ziemlicher Sicherheit die richtige Lösung ist nicht zu versuchen, etwas Ähnliches. null ist schlecht. Casting ist schlecht.

Wenn Sie jedoch zu schreiben Unsinn bestimmt sind, können Sie das Class Objekt übergeben:

public static <T> T evilMethod(Class<T> clazz, Object obj) {
    try {
        return clazz.cast(obj);
    } catch (ClassCastException exc) {
        return null;
    }
}

Andere Tipps

Ich bin sicher nicht ganz wird es wie erwartet funktionieren. (Hängt davon ab, was man natürlich erwarten :-) aber dieser Code wird zum Beispiel in Folge einer java.lang.ClassCastException ( ideone ) :

public class Main {

    public static void main(String[] args) {
        Integer o = Main.<String, Integer>castOrNull("hello");
    }


    public static <X, Y> Y castOrNull(X obj) {
        try {
            return (Y) obj;
        } catch (ClassCastException e) {
            return null;
        }
    }
}

@ Tom Hawtin bekam die "richtige" Lösung .

Sie können die Warnung in diesem Verfahren zu unterdrücken, wenn Sie sicher wissen, dass es nicht ein Problem, indem sie sie mit @SuppressWarnings("unchecked") Anmerkungen versehen

Durch die Art und Weise Java-Generika, wo Sie diesen Code nicht funktioniert überhaupt entwickelt. Generika sind nur nützlich für die Kompilierung Typprüfung als die Klassen nicht generische Typinformationen zur Laufzeit verwenden Sie.

Ihr Code wird dazu erstellt werden:

 static Object castOrNull(Object obj) {
  try {
   return (Object)obj;//FAIL: this wont do anything
  }
  catch(ClassCastException e) {
   return null;
  }
 }

Die Besetzung zu Objekt wird nie scheitern, und der kompilierte Code hat keinen Zugriff auf den generischen Typen vorhanden bei der Kompilierung. Da die Besetzung nicht so, wie kommt es, sollte eine Warnung für einen unkontrollierten Betrieb erhalten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top