2008-10-28 4 views
12

einigen Code Blick durch ich über den folgenden Code kamWann sollte ich die Java 5-Methode von Class verwenden?

trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto)); 

und ich möchte, wenn Gießen auf diese Weise alle Vorteile gegenüber

muss wissen,
trTuDocPackTypdBd.update((TrTuDocPackTypeDto)packDto); 

ich die Entwickler verantwortlich und er gefragt haben Ich sagte, er benutzte es, weil es neu war (was für mich kein besonders guter Grund ist), aber ich bin fasziniert, wenn ich diese Methode anwenden möchte.

+0

siehe auch http://stackoverflow.com/questions/7900410/why-would-i-use-javal-lang-class-cast/7902048#7902048 – irreputable

Antwort

20

Diese Aussagen sind nicht identisch. Die Cast-Methode ist ein normaler Methodenaufruf (invokevirtual JVM-Anweisung), während die andere ein Sprachkonstrukt (checkcast-Anweisung) ist. Im Fall, dass Sie oben zeigen, sollten Sie das zweite Formular: (TrTuDocPackTypeDto) packDto

Die cast Methode wird in der reflektierenden Programmierung mit Generika verwendet, wenn Sie eine Klasseninstanz für einige Variablentypen haben. Man könnte es wie folgt verwenden:

public <T> Set<T> find(Class<T> clz, Filter criteria) { 
    List<?> raw = session.find(clz, criteria); /* A legacy, un-generic API. */ 
    Set<T> safe = new HashSet<T>(); 
    for (Object o : raw) 
    safe.add(clz.cast(o)); 
    return safe; 
} 

Dies gibt Ihnen eine sichere Art und Weise die falsche Alternative einfach Gießen eines rohen Art auf eine generische Art zu vermeiden:

/* DO NOT DO THIS! */ 
List raw = new ArrayList(); 
... 
return (List<Widget>) raw; 

Der Compiler wird Sie warnen, Unchecked cast from List to List<Widget> Das bedeutet, dass in den Ellipsen eine Person Gadget zur unformatierten Liste hinzugefügt haben könnte, was schließlich zu einer ClassCastException führen würde, wenn der Aufrufer über die zurückgegebene Liste von (angenommenen) Widget Instanzen iteriert.

+0

Bei einem schnellen Scan der Sprachreferenz scheint es, dass die 'class.cast()' würde die Warnung 'unsafe conversion' umgehen, die der Compiler normalerweise anzeigt. Als erickson sagte, verwenden Sie das Sprachkonstrukt, bis Sie nicht können. ;-) –

+0

Können Sie erklären, was Sie im zweiten Fall tun sollten? Ich bin gestern nur auf diese Compiler-Warnung gestoßen, habe sie aber ignoriert, weil ich faul bin. Schlägst du etwas vor wie List .cast (roh)? –

+0

@Outlaw - um den zweiten Fall zu vermeiden, müssen Sie etwas verwenden, wie ich es in der "Finde" -Methode oben angegeben habe. Das heißt, Sie müssen über die "Liste" iterieren und testen, dass jedes Element wirklich ein "Widget" ist. Dann wäre es in Ordnung, die Warnung zu ignorieren, die Sie von "(Liste ) roh" erhalten. – erickson

-3

Beide Aussagen sind identisch. Wählen Sie den, den Sie besser finden. Die zweite Methode ist häufiger in meiner Erfahrung, und es ist die eine, die ich bevorzuge.

Ich neige dazu, die Cast-Methode nur zu verwenden, wenn ich mit Reflexion arbeite, und es liest sich besser in dieser Situation. Alle anderen Male benutze ich die zweite Art zu Casting.

4

Der Hauptgrund dafür (IME) ist, wenn Sie eine generische Klasse/Methode sicher einbetten müssen. Aufgrund der Typlöschung können Sie nicht in T umwandeln. Wenn Sie jedoch einen Class<? extends T>-Parameter erhalten haben, können Sie diesen verwenden und das Ergebnis kann einer Variablen vom Typ T zugewiesen werden.

0

Ich kann kein Beispiel finden, wo die Cast-Methode möglich ist und die Cast-Syntax nicht. Wenn man jedoch den Code betrachtet, scheint die Cast-Methode, falls die Umwandlung nicht möglich ist, eine ClassCastException ohne angehängte Typinformation auszulösen, während die Cast-Syntax einige Hinweise liefert (wie zB "Snoopy konnte nicht gecastet werden TyrannosorusRex ") :

/** 
* Casts an object to the class or interface represented 
* by this <tt>Class</tt> object. 
* 
* @param obj the object to be cast 
* @return the object after casting, or null if obj is null 
* 
* @throws ClassCastException if the object is not 
* null and is not assignable to the type T. 
* 
* @since 1.5 
*/ 
public T cast(Object obj) { 
if (obj != null && !isInstance(obj)) 
    throw new ClassCastException(); 
return (T) obj; 
} 
+0

Class.cast() ist nützlich, wenn Sie nicht wissen, an welche Klasse Sie gerade denken (d. H. Reflexion usw.). Im Allgemeinen sollten Sie zuerst Class.isInstance (Object) überprüfen, um sicherzustellen, dass Sie kein CCE erhalten. –

0

Mit der ersten Form

trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto)); 

Sie können dies tun:

public void dynamicCast(Class clazz, Object o) { 
    this.x = clazz.cast(o); 
} 

Mit th Die Sekunde kannst du nicht. Die Casting-Klasse sollte fest codiert sein.

Warum würden Sie eine Variable verwenden, um an erster Stelle zu werfen? Das ist eine andere Frage.:) Die erste Sache, die dir in den Sinn kommt, ist, dass du zur Kompilierzeit nicht weißt, in welche Klasse gewirkt wird.

Verwandte Themen