Es gibt Situationen, in denen es praktisch ist, wenn ein Typ-Cast einen Null-Wert zurückgibt, anstatt eine ClassCastException auszulösen. C# hat dafür den Operator as
. Ist in Java etwas Entsprechendes verfügbar, sodass Sie nicht explizit nach der ClassCastException suchen müssen?Wie man C# as-operator in Java emuliert
Antwort
Hier ist eine Implementierung als, wie @Omar Kooheji vorgeschlagen:
public static <T> T as(Class<T> clazz, Object o){
if(clazz.isInstance(o)){
return clazz.cast(o);
}
return null;
}
as(A.class, new Object()) --> null
as(B.class, new B()) --> B
Sie können das instanceof
Schlüsselwort anstelle von C# is
verwenden, aber es gibt nichts wie as
.
Beispiel:
if(myThing instanceof Foo) {
Foo myFoo = (Foo)myThing; //Never throws ClassCastException
...
}
Ja, die alte Doppelbesetzung. Schade Java hat nicht etwas so Elegantes wie der 'as' Operator. –
'as' ist eine sehr nützliche Sache. –
Ich denke, würden Sie Ihre eigene Rolle müss:
return (x instanceof Foo) ? (Foo) x : null;
EDIT: Wenn Sie nicht Ihre Kundennummer wollen mit Nullen beschäftigen, dann Sie können ein Null Object
interface Foo {
public void doBar();
}
class NullFoo implements Foo {
public void doBar() {} // do nothing
}
class FooUtils {
public static Foo asFoo(Object o) {
return (o instanceof Foo) ? (Foo) o : new NullFoo();
}
}
class Client {
public void process() {
Object o = ...;
Foo foo = FooUtils.asFoo(o);
foo.doBar(); // don't need to check for null in client
}
}
ich spekulierte einführen Sie propably ein als Betreiber creas könnte
so etwas wie
as<T,Type> (left, right)
which evaluates to
if (typeof(left) == right)
return (right)left
else
return null
Ich bin nicht sicher, wie Sie es tun würde, ich bin ein C# im Moment und mein Java Hut hat sich ein wenig staubig geworden, seit ich Universität verlassen.
Konkreter Typvergleich, d. H. 'Typeof (links) == right' ist nicht das' '' '. – weston
Sie könnten eine statische Hilfsmethode wie diese schreiben. Ich denke nicht, dass es schrecklich lesbar ist, aber es ist die beste Annäherung an das, was Sie versuchen zu tun. Und wenn Sie statische Importe verwenden, wäre es nicht schlecht in Bezug auf die Lesbarkeit.
package com.stackoverflow.examples;
public class Utils {
@SuppressWarnings("unchecked")
public static <T> T safeCast(Object obj, Class<T> type) {
if (type.isInstance(obj)) {
return (T) obj;
}
return null;
}
}
Hier ist ein Testfall, der zeigt, wie es funktioniert (und dass es funktioniert.)
package com.stackoverflow.examples;
import static com.stackoverflow.examples.Utils.safeCast;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import org.junit.Test;
public class UtilsTest {
@Test
public void happyPath() {
Object x = "abc";
String y = safeCast(x, String.class);
assertNotNull(y);
}
@Test
public void castToSubclassShouldFail() {
Object x = new Object();
String y = safeCast(x, String.class);
assertNull(y);
}
@Test
public void castToUnrelatedTypeShouldFail() {
Object x = "abc";
Integer y = safeCast(x, Integer.class);
assertNull(y);
}
}
Dies funktioniert nicht wirklich. isAssignableFrom testet, ob obj eine Instanz einer Superklasse von T ist. Daher gibt safeCast (new Object(), A.class) .doA() eine Klassenausnahme und nicht eine NPE zurück. –
hast du recht. Ich hatte die zwei Klassenobjekte rückwärts. Ich habe die Antwort bearbeitet und sie sollte nun korrekt sein. –
Gibt es einen bestimmten Grund für die Verwendung von type.isAssignableFrom (obj.getClass() anstelle von type.isInstance (obj)? – VoidPointer
In Java 8 können Sie auch Stream-Syntax mit Optional verwenden:
Aaron, was ist, wenn ich einen generischen Typ als Clazz-Parameter an Ihre "as" -Funktion übergeben möchte? – mfalto
Selbstantwort ... das kann nicht gemacht werden in Java wegen Typ löschen – mfalto
Ich mag das Design der oben genannten Funktion 'as', aber es stört mich die Tatsache, dass die' isInstance' Methode wird zweimal aufgerufen, aufgrund der Verwendung der 'Cast' Methode der Klasse' Klasse ".Intern verwendet diese Methode die IsIsntance-Methode, um die Kompatibilität zwischen den Typen zu überprüfen. Nichtsdestoweniger können wir erwarten, dass die JVM den 'cast' Code innerhalb der gegebenen' as' Funktion inline und danach der Jitter redundante Aufrufe der 'IsInstance' Methode entfernen kann, aber darüber können wir nicht sicher sein. –