2011-12-27 65 views
19

假设我有两个班,从第三个抽象类派生:通过做在Java中是否存在“类型安全”转换的形式?

public abstract class Parent{ 
    public Parent(){ 
    } 
} 

public class ChildA extends Parent { 
    public ChildA { 
    } 
} 

public class ChildB extends Parent { 
    public ChildB { 
    } 
} 

在C#中我能胜任在有些类型安全的方式铸:

ChildA child = obj as ChildA; 

这将使孩子== NULL如果它不是一个ChildA类型的对象。如果我这样做:

ChildA child = (ChildA)obj; 

...在C#中,如果类型不正确,会引发异常。

所以基本上,有没有办法在Java中进行第一种类型的投射?谢谢。

+0

复制:http://stackoverflow.com/questions/148828/how-to-emulate-c-sharp-as-operator-in-java – 2011-12-27 22:37:26

+0

道歉。我搜索了“类型安全铸造java”。我没有想到要搜索“as keyword java”。 – garrettendi 2011-12-27 22:53:14

+3

然后它爆炸与NPE。 ;) – 2011-12-27 22:53:40

回答

47

我想不出在语言本身的一种方式,但你可以很容易地模仿它是这样的:

ChildA child = (obj instanceof ChildA ? (ChildA)obj : null); 
+0

怎么样obj instanceof列表? (列表)obj:null?您不能使用泛型类型的实例,因为它在运行时会消失。 – vajanko 2014-11-16 10:46:44

+0

@vajanko您说得对,如果您还需要检查项目类型,则无法使用泛型类型。你仍然可以做'列表? (List)obj:null' - 但你会得到编译时警告。这个问题没有提及任何有关泛型的内容。 – 2014-11-16 18:19:15

5

您可以使用instanceof运算符。

if(obj instanceof ChildA){ 
    final ChildA child = (ChildA) obj; 
} 
2

你可以随时检查第一:

if (child instanceof ChildA) { 
    ChildA child = (ChildA) child; 
    // Do stuff. 
} 

或者只是做一个快速的方法:

public ChildA getInstance(Parent p) { 
    if (child instanceof ChildA) { 
     return (ChildA) p; 
    } else { 
     return null; 
    } 
} 
9

在java 8你也可以使用可选的流语法:

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")); 
1

我认为处理这个问题的最好方法是使用泛型方法。 这是我认为最可重用/安全的选项。

这里就是我来:

@SuppressWarnings("unchecked") 
public <E> E coerceTo(Object o, Class<E> target) throws IllegalArgumentException { 
    if(target.isInstance(o)) return (E)o; 
    String msg = "expected "+target.getName()+" but was "+o.getClass().getName(); 
    throw new IllegalArgumentException(msg); 
} 

注意的是,这里,演员是安全的,这是正确的添加suppressWarnings注解。

下面是如何调用该方法的例子:

Object o = 1; 
int a = coerceTo(o, Integer.class); 
2

您可以使用此方法,它与所有的Java类型兼容:

public static <T> T safeCast(Object o, Class<T> clazz) { 
    return clazz != null && clazz.isInstance(o) ? clazz.cast(o) : null; 
} 

例子:

// A given object obj 
Integer i = safeCast(obj, Integer.class); 
相关问题