суббота, 15 сентября 2007 г.

Java Puzzle 44: Cutting Class

Рассмотрим следующие классы:
public class Missing {
    public Missing() {
    }
}
public class First {
    public static void main(String[] args) {
        try {
            Missing m = new Missing();
        } catch (NoClassDefFoundError error) {
            System.out.println("Got it!");
        }
    }
}
public class Second {
    public static void main(String[] args) {
        Missing m;
        try {
            m = new Missing();
        } catch (NoClassDefFoundError error) {
            System.out.println("Got it!");
        }
    }
}
Если скомпилировать все три класса, а затем удалить файл Missing.class, то можно обнаружить, что программы First и Second выполняются по разному. Одна из них генерирует исключение NoClassDefFoundError, а вторая печатает Got it!
Можете определить и объяснить, как выполняется каждая из программ?

Программа First содержит удаленный класс только внутри блока try, поэтому можно ожидать, что исключение NoClassDefFoundError будет перехвачено и программа напечатает Got it! Программа Second содержит удаленный класс вне блока try, поэтому можно ожидать, что исключение NoClassDefFoundError не будет перехвачено. Однако, если запустить обе программы, то можно убедится, что они ведут себя совсем наоборот!

Проблема заключается в небольшой разнице в скомпилированном коде. А если необходимо определить, что класс пропал, используйте reflection:
public class Third {
    public static void main(String[] args) {
        try {
            Object m = Class.forName("Missing").newInstance();
        } catch (ClassNotFoundException exception) {
            System.out.println("Got it!");
        }
    }
}
Но самый главный совет: не перехватывайте Error или его подклассы. Эти исключения зарезервированы для проблем, после которых невозможно восстановиться...

Комментариев нет:

Отправить комментарий