在Java中是否存在一种“类型安全”的转换?

时间:2022-04-24 16:28:30

Suppose I have two classes deriving from a third abstract class:

假设我有两个派生自第三个抽象类的类:

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

public class ChildA extends Parent {
    public ChildA {
    }
}

public class ChildB extends Parent {
    public ChildB {
    }
}

In C# I could handle casting in a somewhat type safe manner by doing:

在C#中,我可以通过以下方式处理某种类型安全的方式:

ChildA child = obj as ChildA;

Which would make child == null if it wasn't a ChildA type object. If I were to do:

如果它不是ChildA类型对象,那么会使child == null。如果我这样做:

ChildA child = (ChildA)obj;

...in C# this would throw an exception if the type wasn't correct.

...在C#中,如果类型不正确,则会抛出异常。

So basically, is there a way to to do the first type of casting in Java? Thanks.

基本上,有没有办法在Java中进行第一种类型的转换?谢谢。

6 个解决方案

#1


48  

I can't think of a way in the language itself, but you can easily emulate it like this:

我无法想到语言本身的一种方式,但你可以像这样轻松地模仿它:

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

#2


12  

In java 8 you can also use stream syntax with Optional:

在java 8中,您还可以使用带有Optional的流语法:

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

#3


6  

You can use the instanceof operator.

您可以使用instanceof运算符。

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

#4


3  

You can use this method which is compatible with all java types :

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

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

Example :

示例:

// A given object obj
Integer i = safeCast(obj, Integer.class);

#5


2  

You can always just check first:

你总是可以先检查一下:

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

Or just make a quick method:

或者只是快速方法:

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

#6


1  

I think the best way to deal with this is to use generic methods. This is to my opinion the most reusable/safe option.

我认为解决这个问题的最佳方法是使用泛型方法。这是我认为最可重用/安全的选择。

Here's what i've come to:

这就是我要来的:

@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);
}

Note that here, the cast is safe and it's correct to add the suppressWarnings annotation.

请注意,在这里,强制转换是安全的,添加suppressWarnings注释是正确的。

Here's an example of how to call the method:

以下是如何调用该方法的示例:

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

#1


48  

I can't think of a way in the language itself, but you can easily emulate it like this:

我无法想到语言本身的一种方式,但你可以像这样轻松地模仿它:

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

#2


12  

In java 8 you can also use stream syntax with Optional:

在java 8中,您还可以使用带有Optional的流语法:

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

#3


6  

You can use the instanceof operator.

您可以使用instanceof运算符。

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

#4


3  

You can use this method which is compatible with all java types :

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

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

Example :

示例:

// A given object obj
Integer i = safeCast(obj, Integer.class);

#5


2  

You can always just check first:

你总是可以先检查一下:

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

Or just make a quick method:

或者只是快速方法:

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

#6


1  

I think the best way to deal with this is to use generic methods. This is to my opinion the most reusable/safe option.

我认为解决这个问题的最佳方法是使用泛型方法。这是我认为最可重用/安全的选择。

Here's what i've come to:

这就是我要来的:

@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);
}

Note that here, the cast is safe and it's correct to add the suppressWarnings annotation.

请注意,在这里,强制转换是安全的,添加suppressWarnings注释是正确的。

Here's an example of how to call the method:

以下是如何调用该方法的示例:

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