“Динамический” кастинг в Java

Вы можете использовать Optional:

Optional.ofNullable(model)
        .map(Model::getFoo)
        .ifPresent(foo -> {
            switch (foo) { // or if-else-if, the important thing is you skip the null check
                case 1: 
                    ...
                    break;
                case 2:
                    ...
                    break;
                ...
            }

        });
5
задан user50264 30 December 2008 в 20:51
поделиться

7 ответов

(Не может добавить код в комментарии, таким образом, я добавлю здесь),

Оценка Cloneable: если Вы реализуете Cloneable, реализуете его следующим образом; намного более чистый для вызова...

public class Foo implements Cloneable {
    public Foo clone() {
        try {
            return (Foo) super.clone();
        } catch (CloneNotSupportedException e) {
            return null; // can never happen!
    }
}

[РЕДАКТИРОВАНИЕ: я также видел, что другие люди используют

throw new AssertionError("This should never happen! I'm Cloneable!");

в блоке выгоды.]

1
ответ дан 18 December 2019 в 06:36
поделиться

Похож на попытку сделать это:

  public Object copy(){
       return new Object();
  }

И затем попытка к:

  String s = ( String ) copy();

Ваш класс Родительского класса и ChildN имеет те же отношения как Объект и Строка

Чтобы заставить его работать, необходимо было бы сделать следующее:

public class ChildN extends Parent {
    public Parent copy() {
        return new ChildN();
    }
}

Таким образом, переопределите метод "копии" и возвратите правильный экземпляр.


Править

Согласно Вашему редактированию. Это на самом деле возможно. Это могло быть одним возможным путем:

public class Parent {
    public Parent copy() {
        Parent copy = this.getClass().newInstance();
        //...
        return copy;
    }
}

Тем путем Вы не должны переопределять метод "копии" в каждом подклассе. Это - Опытный шаблон разработки.

Однако с помощью этой реализации необходимо знать две контролируемых исключительных ситуации. Вот полная программа, которая компилирует и работает без проблем.

public class Parent {
    public Parent copy()  throws InstantiationException, IllegalAccessException  {
       Parent copy = this.getClass().newInstance();
       //...
       return copy;
    }
}
class ChildN  extends Parent {}

class Driver {
     public static void main(String[] args) throws  InstantiationException ,  IllegalAccessException  {
         ChildN orig = new ChildN();
         ChildN copy = orig.getClass().cast(orig.copy());
         System.out.println( "Greetings from : " + copy );
    }
}
9
ответ дан 18 December 2019 в 06:36
поделиться

Если ChildN не переопределяет копию () для возврата экземпляра ChildN, то Вы пробуете к удрученному объект родителя типа ввести ChildN

4
ответ дан 18 December 2019 в 06:36
поделиться

Состав исполнителей эффективно пытается сделать это:

ChildN copy = (ChildN) orig.copy();

(Это разрабатывает бросок для выполнения во время выполнения, но это - то, чем это будет потому что orig.getClass() будет ChildN.class) Однако orig.copy() не возвращает экземпляр ChildN, он возвращает экземпляр просто Parent, таким образом, это не может быть брошено к ChildN.

6
ответ дан 18 December 2019 в 06:36
поделиться

Могло случиться так простым желанием копии/клона объекта.

В этом случае реализуйте интерфейс Cloneable и переопределите клон () по мере необходимости.

public class Parent implement Cloneable {
   public Object clone() throws CloneNotSupportedException {
     Parent aCopy = (Parent) super.clone();
   ...
   return aCopy;
   }
}

public class ChildN extends Parent {
    ...
}

public class Driver {
     public static void main(String[] args) {
         ChildN orig = new ChildN();
         ...
         ChildN copy = orig.getClass().cast(orig.clone());
     }
}

Это делает точно, что Ваша "копия ()" метод пыталась сделать в Java путь.

(Да, Вы могли сделать необычные игры самоанализа также, но те методы сбой или стать уродливыми, как только у Вас нет общедоступного конструктора по умолчанию. Клон работает в любом случае, каких конструкторов Вы имеете.)

2
ответ дан 18 December 2019 в 06:36
поделиться

Причина downcasting не работает, то, потому что при кастинге родительского объекта к дочернему типу нет никакого способа, которым можно вызвать методы дочернего типа на родительский объект. Но это работает другой путь...

0
ответ дан 18 December 2019 в 06:36
поделиться

java.lang. Class#cast (Объект) бросает ClassCastException, если Class#isInstance () возвращает false. От javadoc для того метода:

Определяет, совместим ли указанный Объект с присвоением с объектом, представленным этим Классом. Этот метод является динамическим эквивалентом оператора instanceof языка Java... А именно, если это Class объект представляет заявленный класс, этот метод возвраты true если указанное Object аргументом является экземпляр представленного класса (или любого из его подклассов); это возвращается false иначе.

Так как Родитель не является подклассом ребенка, isInstance () возвращает false, таким образом, бросок () выдает исключение. Это может нарушить принцип наименьшего количества удивления, но это прокладывает себе путь, это зарегистрировало - бросок () может только восходящий, не удрученный.

2
ответ дан 18 December 2019 в 06:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: