在某些情况下,使用类型转换返回null值而不是抛出ClassCastException是切实可行的.C#让as
操作员这样做.Java中是否存在等效的东西,因此您不必显式检查ClassCastException?
这是@Omar Kooheji所建议的as的实现:
public staticT as(Class 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
我认为你必须自己动手:
return (x instanceof Foo) ? (Foo) x : null;
编辑:如果您不希望您的客户端代码处理空值,那么您可以引入一个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 } }
您可以使用instanceof
关键字代替C#is
,但没有什么比这更好的了as
.
例:
if(myThing instanceof Foo) { Foo myFoo = (Foo)myThing; //Never throws ClassCastException ... }
您可以编写这样的静态实用程序方法.我不认为它非常易读,但它是你想要做的最好的近似.如果你使用静态导入,那么在可读性方面也不会太糟糕.
package com.stackoverflow.examples; public class Utils { @SuppressWarnings("unchecked") public staticT safeCast(Object obj, Class type) { if (type.isInstance(obj)) { return (T) obj; } return null; } }
这是一个测试用例,演示了它是如何工作的(并确实有效).
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); } }