Frage

Es gibt Situationen, in denen es sinnvoll ist, ein haben Typ-Cast einen Nullwert zurückgeben, anstatt eine Classcast zu werfen. C # hat den as Betreiber, dies zu tun. Gibt es etwas Gleichwertiges in Java so dass Sie sich nicht explizit für den Classcast überprüfen?

War es hilfreich?

Lösung

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

Andere Tipps

Ich würde denken, dass Sie rollen müssten Sie Ihre eigenen:

return (x instanceof Foo) ? (Foo) x : null;

EDIT: Wenn Sie nicht Ihre Kundennummer wollen mit Nullen beschäftigen, dann können Sie eine Null Objekt

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
    }
}

Sie können das instanceof Schlüsselwort anstelle von C # 's is verwenden, aber es gibt nichts wie as.

Beispiel:

if(myThing instanceof Foo) {
   Foo myFoo = (Foo)myThing; //Never throws ClassCastException
   ...
}

Sie können eine statische Hilfsmethode so schreiben. Ich glaube nicht, es schrecklich lesbar ist, aber es ist die beste Annäherung von dem, was Sie zu tun versuchen. Und wenn Sie statische Importe verwenden würde es nicht so schlimm sein, 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);
    }
}

In Java 8 Sie auch Stream-Syntax mit Optional können:

Object o = new Integer(1);

Optional.ofNullable(o)
        .filter(Number.class::isInstance)
        .map(Number.class::cast)
        .ifPresent(n -> System.out.print("o is a number"));

Ich spekuliert man kann propably creas ein als Operator

so etwas wie

as<T,Type> (left, right)  
which evaluates to 
if (typeof(left) == right)
   return (right)left
else
    return null

Ich bin mir 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.

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