Как Java обнаруживает проверенные исключения?

Если я напишу такие вещи:

public static void main(String[] args) {
    try {
    } catch (MalformedURLException e) { 
        e.printStackTrace()
    };
}

Компилятор Java показывает ошибку компиляции в предложении catch MalformedURLException, Если я вставлю строку URL url = new URL("HI"); в блоке try, жалоба прекращается. Я думал, что Java должен связывать эти проверенные исключения с пакетом. Затем я попробовал другой класс пакета java.net, вставив " CookieManager manager = new CookieManager(); "только в блоке try. Ошибка компиляции снова начинается.

Так как же JVM связывает эти проверенные исключения с java-классами для подобных ошибок времени компиляции?

5 ответов

Решение

Объявление метода указывает, какие исключения вызывает метод. Эта информация доступна для компилятора. Компилятор выдает сообщение об ошибке, если вы пытаетесь перехватить исключение, которое не может быть вызвано кодом, вызванным в предложении try.

В случае Проверенных Исключений что-то должно быть брошено, прежде чем оно будет поймано!

public static void main(String[] args) {
    try {
    } catch (MalformedURLException e) {
        e.printStackTrace()
    };
}

В этом нет возможности выбросить исключение, поэтому вы не можете его поймать.

Когда вы добавляете

URL url = new URL("HI");

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

public URL(String protocol, String host, int port, String file)
    throws MalformedURLException
{
    this(protocol, host, port, file, null);
}

Но конструктор CookieManager не выдает никаких исключений. Так что не надо его ловить.

/**
 * Create a new cookie manager.
 *
 * <p>This constructor will create new cookie manager with default
 * cookie store and accept policy. The effect is same as
 * <tt>CookieManager(null, null)</tt>.
 */
public CookieManager() {
    this(null, null);
}

Для каждого метода проверенные исключения сохраняются в файле класса.

Когда вы вызываете такой метод с проверенным исключением, компилятор проверяет, что вы либо перехватили исключение, либо выбросили его из вашего метода.

С http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html:

14,21. Недоступные заявления

Это ошибка времени компиляции, если оператор не может быть выполнен, потому что он недоступен.

...

Блок перехвата C доступен, если выполняются оба следующих условия:

  • Либо тип параметра C является непроверенным типом исключения, либо Throwable; или какое-либо выражение или оператор throw в блоке try достижим и может выдать проверенное исключение, тип которого можно назначить параметру предложения catch C.

Выражение достижимо, если достижимо самое внутреннее утверждение, содержащее его.

См. §15.6 для нормального и внезапного завершения выражений.

  • В операторе try нет более раннего блока catch A, так что тип параметра C совпадает с типом параметра A или является его подклассом.

Первое условие неверно, если блок try пуст: нет ничего, что "может выдать проверенное исключение, тип которого можно назначить параметру в предложении catch C".

Это просто супер бдительный компилятор Java, который жалуется на то, что: если вы не генерируете какое-либо исключение, вы не вызываете какой-либо код, который его генерирует, тогда почему у вас бесполезный блок try-catch, который тратит впустую пространство?

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

Другие вопросы по тегам