How to emulate C# as-operator in Java

JavaCasting

Java Problem Overview


There are situations, where it is practical to have a type-cast return a null value instead of throwing a ClassCastException. C# has the as operator to do this. Is there something equivalent available in Java so you don't have to explicitly check for the ClassCastException?

Java Solutions


Solution 1 - Java

Here's an implementation of as, as suggested by @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

Solution 2 - Java

I'd think you'd have to roll your own:

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

EDIT: If you don't want your client code to deal with nulls, then you can introduce a 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
    }
}

Solution 3 - Java

You can use the instanceof keyword in place of C#'s is, but there is nothing like as.

Example:

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

Solution 4 - Java

You could write a static utility method like this. I don't think it's terribly readable, but it's the best approximation of what you're trying to do. And if you use static imports it wouldn't be too bad in terms of readability.

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

Here's a test case that demonstrates how it works (and that it does work.)

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

Solution 5 - Java

In java 8 you can also use stream syntax with 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"));

Solution 6 - Java

I'm speculating you could propably creas an as operator

something like

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

I'm not sure how you'd do it, I'm a c# at the moment and my Java hat has gotten a bit dusty since I left university.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVoidPointerView Question on Stackoverflow
Solution 1 - JavaAaron MaenpaaView Answer on Stackoverflow
Solution 2 - JavatoolkitView Answer on Stackoverflow
Solution 3 - JavaChris Marasti-GeorgView Answer on Stackoverflow
Solution 4 - JavaMike DeckView Answer on Stackoverflow
Solution 5 - JavaDmitry KlochkovView Answer on Stackoverflow
Solution 6 - JavaOmar KoohejiView Answer on Stackoverflow