49 votes

Comment émuler C# en tant que opérateur en Java

Il y a des situations où il est pratique de disposer d'un type de fonte retourner une valeur null au lieu de lancer une ClassCastException. C# a as de l'opérateur pour ce faire. Est-il quelque chose d'équivalent en Java disponible de sorte que vous n'avez pas explicitement à vérifier pour la ClassCastException?

55voto

Aaron Maenpaa Points 39173

Voici une implémentation de que, 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

25voto

toolkit Points 27248

Je pensais que vous auriez à rouler:

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

EDIT: Si vous ne voulez pas que votre code client à traiter avec les valeurs null, vous pouvez introduire un Objet Null

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

15voto

Chris Marasti-Georg Points 17023

Vous pouvez utiliser l' instanceof mot-clé à la place de C# is, mais il n'y a rien comme as.

Exemple:

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

12voto

Mike Deck Points 7443

Vous pourriez écrire un statique méthode utilitaire de ce genre. Je ne pense pas que c'est très lisible, mais c'est la meilleure approximation de ce que vous essayez de faire. Et si vous utiliser des importations, elle ne devrait pas être trop mauvais en termes de lisibilité.

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 cas de test qui montre comment ça marche (et que ça 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);
    }
}

-2voto

Omar Kooheji Points 14073

Je suis en spéculant vous pourriez probablement creas un 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 suis pas sûr de savoir comment vous le ferais, je suis un c# en ce moment et ma Java hat a eu un peu poussiéreux depuis que j'ai quitté l'université.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X