Question

Il existe des situations dans lesquelles il est pratique de demander à une conversion de type de renvoyer une valeur null au lieu de générer une exception ClassCastException. C # a l'opérateur en tant que pour le faire. Y at-il quelque chose d’équivalent disponible en Java, vous n’avez donc pas à vérifier explicitement l’exception ClassCastException?

Était-ce utile?

La solution

Voici une implémentation de as, comme suggéré par @Omar Kooheji:

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

Autres conseils

Je pense que vous devrez rouler vous-même:

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

EDIT: si vous ne souhaitez pas que votre code client traite les valeurs null, vous pouvez introduire un Null. Objet

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

Vous pouvez utiliser le mot clé instanceof à la place du de C #, <, mais rien ne ressemble à en tant que .

Exemple:

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

Vous pourriez écrire une méthode d’utilité statique comme celle-ci. Je ne pense pas que ce soit très lisible, mais c'est la meilleure approximation de ce que vous essayez de faire. Et si vous utilisez des importations statiques, la lisibilité ne serait pas trop grave.

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

Voici un scénario de test qui montre comment cela fonctionne (et que cela fonctionne.)

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

En Java 8, vous pouvez également utiliser la syntaxe de flux avec Optional:

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"));

Je pense que vous pourriez probablement créer un en tant qu'opérateur

quelque chose comme

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

Je ne sais pas comment vous allez le faire, je suis c # pour le moment et mon chapeau Java est devenu un peu poussiéreux depuis que j'ai quitté l'université.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top