Как 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, который тратит впустую пространство?
Итак, когда вы даете компилятору повод полагать, что в этом блоке может возникнуть исключение, оно закрывается.