Вы можете использовать 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;
...
}
});
(Не может добавить код в комментарии, таким образом, я добавлю здесь),
Оценка 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!");
в блоке выгоды.]
Похож на попытку сделать это:
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 );
}
}
Если ChildN не переопределяет копию () для возврата экземпляра ChildN, то Вы пробуете к удрученному объект родителя типа ввести ChildN
Состав исполнителей эффективно пытается сделать это:
ChildN copy = (ChildN) orig.copy();
(Это разрабатывает бросок для выполнения во время выполнения, но это - то, чем это будет потому что orig.getClass()
будет ChildN.class
) Однако orig.copy()
не возвращает экземпляр ChildN, он возвращает экземпляр просто Parent
, таким образом, это не может быть брошено к ChildN
.
Могло случиться так простым желанием копии/клона объекта.
В этом случае реализуйте интерфейс 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 путь.
(Да, Вы могли сделать необычные игры самоанализа также, но те методы сбой или стать уродливыми, как только у Вас нет общедоступного конструктора по умолчанию. Клон работает в любом случае, каких конструкторов Вы имеете.)
Причина downcasting не работает, то, потому что при кастинге родительского объекта к дочернему типу нет никакого способа, которым можно вызвать методы дочернего типа на родительский объект. Но это работает другой путь...
java.lang. Class#cast (Объект) бросает ClassCastException, если Class#isInstance () возвращает false. От javadoc для того метода:
Определяет, совместим ли указанный Объект с присвоением с объектом, представленным этим Классом. Этот метод является динамическим эквивалентом оператора instanceof языка Java... А именно, если это
Class
объект представляет заявленный класс, этот метод возвратыtrue
если указанноеObject
аргументом является экземпляр представленного класса (или любого из его подклассов); это возвращаетсяfalse
иначе.
Так как Родитель не является подклассом ребенка, isInstance () возвращает false, таким образом, бросок () выдает исключение. Это может нарушить принцип наименьшего количества удивления, но это прокладывает себе путь, это зарегистрировало - бросок () может только восходящий, не удрученный.