在Java中,如果转换失败,是否可以尝试进行转换并返回null?
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
@ C.Ross我没有看到该问题中未由isInstance()处理的任何边缘情况。但是,我确实看到isAssignableFrom()所需的null检查会增加不必要的复杂性。
我喜欢上面的函数as的设计,但是由于使用类Class的cast方法,将使两次调用isInstance方法的事实困扰我。在内部,此方法使用IsIsntance方法检查类型之间的兼容性。尽管如此,我们可以预期JVM可以在给定的as函数内内联cast代码,然后Jitter可以删除对isInstance方法的冗余调用,但是我们不能
即使输入对象不是所请求类型的实例," as"关键字也将起作用—如果有任何可能的转换,它将采用它。我是Java的新手,但是上面的代码能做到吗?如果不是,则@ C.Ross可能有一个有效点。尽管如此,还需要检查null(而不是那么复杂)。
@ BrainSlugs83听起来这个方法比真正的as运算符还差一点,因为它不会执行任何类型的强制转换。至于罗斯的评论,他的建议与该问题无关,他没有解释任何好处。
您可以使用instanceof关键字确定是否可以正确投射。
return obj instanceof String?(String)obj: null;
当然可以将其通用化并制成函数,但是我认为问题在于Java必须达到什么目的。
我不确定那是不是shoosh想要的。可能需要一种更通用的方式来处理演员。不过,这将是"如何验证对象是否为给定类的实例"的完美答案:)
需要一个" else"子句...
我认为我们不是在这里为他人解决问题,而是提供指导。因此,指出正确的方向就足够了。
您可以,但是不能用Java中的单个函数:
public B nullCast(Object a) {
if (a instanceof B) {
return (B) a;
} else {
return null;
}
}
编辑:请注意,在不添加目标类的情况下,不能使B类通用(对于本示例)(这与instanceof不能使用通用类型这一事实有关):
public T cast(V obj, Class< T > cls) {
if (cls.isInstance(obj)) {
return cls.cast(obj);
} else {
return null;
}
}
是的,但是我给出的是总体思路,而不是特定的方法。
但是,c#s as适用于空对象。
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,因为强制转换是在方法客户端中执行的。
上面的两个解决方案有些尴尬:
强制转换并捕获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);
您可以捕获以下异常:
Foo f = null;
try {
f = Foo(bar);
}
catch (ClassCastException e) {}
或检查类型:
Foo f = null;
if (bar instanceof Foo)
f = (Foo)bar;
空的catch块是一个非常不好的习惯...实际上,我认为编译器在执行此操作时应该将您当面;而且,无论如何,在不抛出异常的情况下,您绝不应该依赖异常来进行检查。
这就是为什么我也毫无例外地提供了该版本的原因。
在Java中,如果强制转换失败,您将收到ClassCastException。您可以捕获异常并将目标对象设置为null。
AFAIK,这将是其中一种:
SomeClassToCastTo object = null;
try {
SomeClassToCastTo object = SomeClassToCastTo.class.cast(anotherObject);
}
catch (ClassCastException e) {
object = null;
}
丑陋,但它应该做您想要的...
那不是使用反射" cast()"方法的好情况。有关更多信息,请参见stackoverflow.com/questions/243811/。
同意,我很放屁,忘记了instanceof运算符。
在这种情况下可以避免创建异常。异常是对象,因此最好不要不必要地创建它们。
您可以处理此捕获的ClassCastException
每次抛出异常时,都会涉及很多开销。这就是为什么异常应该就是一个"例外"。异常处理应保留给真正异常的事件。当例外成为规则时,您的编程错误。使用类型检查要好得多。