【问题标题】:Equivalent of the C# keyword 'as' in Java等效于 Java 中的 C# 关键字“as”
【发布时间】:2009-06-23 18:12:04
【问题描述】:

在 Java 中,如果转换失败,是否可以尝试转换并返回 null

【问题讨论】:

    标签: c# java casting


    【解决方案1】:
    public static <T> T as(Class<T> t, Object o) {
      return t.isInstance(o) ? t.cast(o) : null;
    }
    

    用法:

    MyType a = as(MyType.class, new MyType());   
    // 'a' is not null
    
    MyType b = as(MyType.class, "");   
    // b is null
    

    【讨论】:

    • @erickson:这太完美了!如果可以的话 +10(我知道可以在这里使用泛型:P)我添加了一个示例用法,如果您愿意,请随时回滚。
    • 不错的设计,但在这种情况下使用isAssignableFrom不是更好吗?
    • @C.Ross 你的意思是t.isAssignableFrom(o.getClass())?为什么会更好?
    • @erickson 它只是处理了一些边缘情况。见Q496928
    • @BrainSlugs83 听起来这种方法与真正的as 运算符相比有点不足,因为它不会执行任何类型的类型强制。至于 C. Ross 的评论,他的建议与该问题无关,他也没有解释其中的任何好处。
    【解决方案2】:

    您可以使用instanceof 关键字来确定您是否可以正确投射。

    return obj instanceof String?(String)obj: null;
    

    当然,它可以被泛型化并制成函数,但我认为问题是 Java 必须通过什么手段来实现这一点。

    【讨论】:

    • 我不确定这就是 shoosh 想要的。可能需要一种更通用的方法来处理演员表。这将是“我如何验证我的对象是给定类的实例”的完美答案:)
    • 我想我们不是来为别人解决问题,而是提供指导。所以指出正确的方向就足够了。
    【解决方案3】:

    您可以,但不能使用 Java 中的单个函数:

    public B nullCast(Object a) {
    
      if (a instanceof B) {
         return (B) a;
      } else {
         return null;
      }
    }
    

    编辑:请注意,如果不添加目标类(这与 instanceof 无法使用泛型类型有关),则不能使 B 类通用(对于此示例):

    public <V, T extends V> T cast(V obj, Class<T> cls) {
      if (cls.isInstance(obj)) {
        return cls.cast(obj);
      } else {
        return null;
      }
    }
    

    【讨论】:

    • 是的,但我给出的是总体思路,而不是具体方法。
    【解决方案4】:
    MyType e = ( MyType ) orNull( object, MyType.class );
    // if "object" is not an instanceof MyType, then e will be null.
    

    ...

    public static Object orNull( Object o , Class type ) { 
        return type.isIntance( o ) ? o : null;
    }
    

    我想这也可以用泛型来完成,但我认为但这可能不是所需要的。

    这个简单的方法接收 Object 并返回 Object,因为转换是在方法客户端中执行的。

    【讨论】:

      【解决方案5】:

      AFAIK,这将是(一种)方法:

      SomeClassToCastTo object = null;
      try {
        SomeClassToCastTo object = SomeClassToCastTo.class.cast(anotherObject);
      }
      catch (ClassCastException e) {
        object = null;
      }
      

      丑,但它应该做你想做的......

      【讨论】:

      • 这不是使用反射“cast()”方法的好例子。请参阅stackoverflow.com/questions/243811/… 了解更多信息。
      • 同意,我脑子里放了个屁,忘记了 instanceof 运算符。
      • 可以避免在这种情况下创建异常。异常是对象,所以最好不要不必要地创建它们。
      【解决方案6】:

      在 Java 中,如果强制转换失败,您将收到 ClassCastException。您可以捕获异常并将目标对象设置为空。

      【讨论】:

        【解决方案7】:

        您可以捕获异常:

        Foo f = null;
        try {
          f = Foo(bar);
        }
        catch (ClassCastException e) {}
        

        或检查类型:

        Foo f = null;
        if (bar instanceof Foo)
          f = (Foo)bar;
        

        【讨论】:

        • 空的 catch 块是一个非常糟糕的习惯......实际上,我认为编译器应该在你这样做的时候打你一巴掌;)。无论如何,您永远不应该依赖异常来检查您可以检查而不会引发异常的事情。
        • 所以我也毫无例外地给出了版本。
        【解决方案8】:

        上面的两种方案都有些别扭:

        铸造和捕获 ClassCastException:创建异常对象可能代价高昂(例如计算堆栈跟踪)。

        前面描述的 nullCast 方法意味着您需要为每个要执行的转换提供一个转换方法。

        因为“类型擦除”,泛型会让你失败......

        您可以创建一个静态辅助方法,保证返回目标类的实例或 null,然后转换结果而不用担心异常:

        public static Object nullCast(Object source, Class target) {
            if (target.isAssignableFrom(source.getClass())) {
                return target.cast(source);
            } else {
                return null;
            }
        }
        

        示例调用:

        Foo fooInstance = (Foo) nullCast(barInstance, Foo.class);
        

        【讨论】:

          【解决方案9】:

          你可以处理这个捕获的 ClassCastException

          【讨论】:

          • 每次抛出异常时,都会涉及很多开销。这就是为什么异常应该只是一个“异常”。异常处理应该保留给真正异常的事件。当例外成为规则时,您的编程错误。使用类型检查要好得多。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-06
          • 2012-12-01
          • 2011-01-29
          • 1970-01-01
          • 2011-01-01
          • 2019-11-09
          相关资源
          最近更新 更多