Как я могу обработать исключение класса Cast, используя регистр переключения?

avatar
Aditya
8 апреля 2018 в 07:55
490
5
0

Где разместить try catch в приведенной ниже программе для обработки исключения приведения класса?

Class Animal { }
Class Dog extends Animal { }
Class Cat extends Animal { }
Class MainRunner {
    public static void main(String args[]) {
        System.out.println("Main method started");
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the key value");
        int key = sc.nextInt();
        Animal a = null;
        switch (key) {
            case 1 : a = new Cat(); break;
            case 2 : a = new Dog(); break;
            default : System.out.println("invalid choice");
            return;
        }
        Dog d = (Dog)a;
        System.out.println("main method ended");
    }
}

Понижение приведения не выполняется для класса Cat, поэтому при вводе значения ключа, равного 1, будет выдано исключение приведения класса. Как справиться с этим, используя try catch ? куда вставить try catch, чтобы он обрабатывался?

Источник
Yassin Hajaj
8 апреля 2018 в 07:58
0

Не могли бы вы правильно сделать отступ в коде, используя улучшитель кода Java?

Pshemo
8 апреля 2018 в 07:58
0

Почему вы хотите обрабатывать исключения? Проверив его тип с помощью instanceof, вы можете предотвратить это. Но если вы должны использовать try-catch, то можете ли вы объяснить, с какими проблемами вы сталкиваетесь при обычном его использовании (мы используем раздел try to wrap, который может генерировать исключение; catch для обеспечения способа его обработки)?

Ответы (5)

avatar
Shadov
8 апреля 2018 в 08:59
0

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

Весь смысл наличия класса Animal состоит в том, чтобы избежать последующего приведения вниз. Ваш коммутатор в основном делает то, что делает Factory Pattern (шаг проверки 3), этот шаблон широко используется в библиотеках и фреймворках, а не только в Java. Тот факт, что вы не знаете, что выходит на заводе, на самом деле хорошо, он дает вам и человеку, который занимается реальной реализацией (это не обязательно должны быть вы), большую гибкость.

Если вы хотите, скажем, привести к Dog, потому что вам нужно вызвать метод bark - не делайте этого, создайте метод makeSound в классе Animal, а затем переопределите/реализуйте его соответствующим образом в классе Dog класс.

avatar
Pradeep
8 апреля 2018 в 08:37
0

Нет необходимости в попытках поймать. вы можете избежать ClassCastException, просто используя оператор instanceof, как показано ниже -

Class Animal { }
Class Dog extends Animal { }
Class Cat extends Animal { }
Class MainRunner {
    public static void main(String args[]) {
        System.out.println("Main method started");
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the key value");
        int key = sc.nextInt();
        Animal a = null;
        switch (key) {
        case 1 : a = new Cat(); break;
        case 2 : a = new Dog(); break;
        default : System.out.println("invalid choice");
        return;
        }
        /* 
         * as per your logic of default block, for invalid choice control is getting 
         * returned back from default block only and if control comes here it means 
         * `a` will not have null value, so skipping null check
         * */
        if(a instanceof Dog){
            Dog d = (Dog)a;
            }
        else{
            Cat c = (Cat)a;
            }
        System.out.println("main method ended");
        }
    }
avatar
Roushan
8 апреля 2018 в 08:30
1

Объявите две переменные каждого типа и инициализируйте их в операторе case.

public class MainRunner {
        public static void main(String args[]) {
            System.out.println("Main method started");
            Scanner sc = new Scanner(System.in);
            System.out.println("Enter the key value");
            int key = sc.nextInt();
            Animal a = null;
            Dog d=null;
            Cat c=null;
            switch (key) {
                case 1 : a = new Cat();
                c=(Cat)a;
                break;
                case 2 : a = new Dog();
                d=(Dog)a;
                break;
                default : System.out.println("invalid choice");
                return;
            }
             if(d!=null){/*  to do */}
             if(c!=null){/*  to do */}
            System.out.println("main method ended");
        }
avatar
hamid ghasemi
8 апреля 2018 в 08:08
0

Не нужно перехватывать исключение, просто используйте метод instanceof перед приведением.

public static void main(String args[]){
        System.out.println("Main method started");
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the key value");
        int key = sc.nextInt();
        Animal a = null;
        switch (key){
            case 1 : a = new Cat(); break;
            case 2 : a = new Dog(); break;
            default : System.out.println("invalid choice");
            return;
        }
        Dog d;
        Cat c;
        if(a!= null && a instanceof Dog)
            d =(Dog)a;
        else if(a!= null && a instanceof Cat)
            c = (Cat)c;

        System.out.println("main method ended");
    }
Pshemo
8 апреля 2018 в 08:11
0

Хотя я согласен с instanceof, как его использование таким образом поможет OP? Теперь область видимости Dog d ограничена только той одной строкой, в которой она была объявлена.

hamid ghasemi
8 апреля 2018 в 08:18
0

@Pshemo, вы правы, я просто предположил, что это пример кода, показывающий использование instanceof, а не реального приложения. немного отредактировал код, но это все равно не чистый код :)

avatar
LoveWithMaths
8 апреля 2018 в 08:06
1

Да, как упомянул @Pshemo; вы должны использовать оператор instanceof, чтобы проверить, является ли его экземпляр Dog, и соответственно инициализировать его

Dog d=null;
if(a instanceof Dog)
  d=(Dog)a;
System.out.println(d);

В идеале вам не нужно опускаться. если вам не нужно вызывать специализированный метод, реализованный вашим подклассом. В противном случае следует использовать метод интерфейса/родительского класса.

example : a.eat() // eat will be present in animal and will be implemented differently in each sub-class dog and cat.

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

if (a instanceof Dog) ((Dog)a).bark();
else syso("Animal cannot bark");