Есть ли в Java форма «безопасного типа»? - PullRequest
29 голосов
/ 28 декабря 2011

Предположим, у меня есть два класса, производных от третьего абстрактного класса:

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;

Что сделало бы child == нулевым, если бы это не был объект типа ChildA. Если бы я должен был сделать:

ChildA child = (ChildA)obj;

... в C # это вызовет исключение, если тип будет неправильным.

Так в принципе, есть ли способ сделать первый тип приведения в Java? Спасибо.

Ответы [ 6 ]

56 голосов
/ 28 декабря 2011

Я не могу придумать способ в самом языке, но вы можете легко подражать ему так:

ChildA child = (obj instanceof ChildA ? (ChildA)obj : null);
12 голосов
/ 12 февраля 2016

В 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"));
9 голосов
/ 21 июня 2017

Вы можете использовать этот метод, который совместим со всеми типами 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);
7 голосов
/ 28 декабря 2011

Вы можете использовать оператор instanceof.

if(obj instanceof ChildA){
     final ChildA child = (ChildA) obj;
}
2 голосов
/ 28 декабря 2011

Вы всегда можете сначала проверить:

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;
    }
}
1 голос
/ 26 ноября 2016

Я думаю, что лучший способ справиться с этим - использовать универсальные методы.На мой взгляд, это самый многоразовый / безопасный вариант.

Вот что я пришел:

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

Обратите внимание, что здесь приведение безопасно и правильно добавить1006 * suppressWarnings аннотация.

Вот пример того, как вызвать метод:

 Object o = 1;
 int a = coerceTo(o, Integer.class);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...