当前位置:  开发笔记 > 编程语言 > 正文

如何在Java中模拟C#as-operator

如何解决《如何在Java中模拟C#as-operator》经验,为你挑选了4个好方法。

在某些情况下,使用类型转换返回null值而不是抛出ClassCastException是切实可行的.C#让as操作员这样做.Java中是否存在等效的东西,因此您不必显式检查ClassCastException?



1> Aaron Maenpa..:

这是@Omar Kooheji所建议的as的实现:

public static  T 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


我喜欢上面函数`as`的设计,但是由于使用类`Class`的`cast`方法,`isInstance`方法将被调用两次,这让我感到困扰.在内部,此方法使用`IsIsntance`方法来检查类型之间的兼容性.尽管如此,我们可以期望JVM可以在给定的`as`函数中内联`cast`代码,之后抖动可以删除对`IsInstance`方法的冗余调用,但我们无法确定.

2> toolkit..:

我认为你必须自己动手:

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



3> Chris Marast..:

您可以使用instanceof关键字代替C#is,但没有什么比这更好的了as.

例:

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


是的,旧的双重演员.Shame Java没有像'as'运算符那样优雅的东西.

4> Mike Deck..:

您可以编写这样的静态实用程序方法.我不认为它非常易读,但它是你想要做的最好的近似.如果你使用静态导入,那么在可读性方面也不会太糟糕.

package com.stackoverflow.examples;
public class Utils {
    @SuppressWarnings("unchecked")
    public static  T 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);
    }
}


不,isInstance可以工作并且更简洁。我本来以为isInstance不适用于子类的实例,但显然可以。答案已更新为使用isInstance,谢谢。
推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有