Что это значит, когда основной метод генерирует исключение?
Я просматриваю среднесрочный период, который я сделал в рамках подготовки к выпускному экзамену завтра утром. Я задал этот вопрос неправильно, но там не было правильного ответа, и я забыл спросить профессора об этом.
Рассмотрим следующий фрагмент кода:
public static void main(String[] args) throws FileNotFoundException
Какое из следующих утверждений об этом коде верно?
- Основной метод предназначен для обнаружения и устранения всех типов исключений.
- Основной метод предназначен для улавливания и обработки
FileNotFoundException
.
- Основной метод должен просто прекратиться, если произойдет
FileNotFoundException
.
- Основной метод должен просто прекращаться, если возникает какое-либо исключение.
Я выбрал второй вариант.
Ответы
Ответ 1
Ответ - номер 4,
4.- Основной метод должен просто прекратиться, если произойдет какое-либо исключение.
В предложении throws указывается, что метод выдает проверенное исключение FileNotFoundException, и вызывающий метод должен поймать или реконструировать его. Если исключенное исключение выбрано (а не catch) в основном методе, оно также прекратится.
Проверьте этот тест:
public class ExceptionThrownTest {
@Test
public void testingExceptions() {
try {
ExceptionThrownTest.main(new String[] {});
} catch (Throwable e) {
assertTrue(e instanceof RuntimeException);
}
}
public static void main(String[] args) throws FileNotFoundException {
dangerousMethod();
// Won't be executed because RuntimeException thrown
unreachableMethod();
}
private static void dangerousMethod() {
throw new RuntimeException();
}
private static void unreachableMethod() {
System.out.println("Won't execute");
}
}
Как вы можете видеть, если я выброшу RuntimeException
, метод завершится, даже если исключение будет не FileNotFoundException
Ответ 2
Чувак, немного поздно, но ответ - номер 3.
Номер 1 является ложным, потому что он не обрабатывает FileNotFoundException
Число 2 неверно по той же причине.
Число 3 истинно. Если выбрано FileNotFoundException, основной метод завершится.
Число 4 неверно. Он не прекращался в случае ЛЮБЫХ исключений. Он прекращается только в случае неконтролируемого исключения или FileNotFoundException. Если нет других проверенных исключений, объявленных в предложении 'throws', это означает, что они обрабатываются внутри метода.
Ответ 3
Основной метод не вылавливает никаких исключений, вместо этого он обрабатывает FileNotFoundException
, выгружая его в источник, который вызывается основным методом.
Время выполнения системы запускает классы JVM, один класс из классов JVM вызывает основной метод.
Обработка основного метода throws
в этом случае будет во власти классов JVM.
- Вы можете прочитать об этом в спецификации языка Java, предоставленной Oracle.
- Кроме того, вы можете просмотреть исходный код для некоторых доступных JVM, перейдя по этому пути, хотя и уберет вас на другие языки программирования, OpenJdk.
Я думал о том, чтобы поделиться своей маленькой смиренной исследовательской корой в этой теме, надеюсь, что это поможет любопытным:)
Ответ 4
Я согласен с некоторыми другими ответами, что правильный ответ на вопрос - это вариант 3. Вариант 4 говорит:
- Основной метод должен просто прекращаться, если возникает какое-либо исключение.
Обратите внимание на "any" в этой опции. Вот пример кода, в котором возникает исключение, но main()
не заканчивается:
public static void main(String[] args) throws FileNotFoundException {
try {
methodThatThrowsACheckedException();
} catch (SomeCheckedException e) {
// do something to handle this exception
}
}
В этом коде возникает исключение, но метод не завершается, поскольку он был настроен для обработки этого исключения. Если исключение было uncaught UncheckedException
, то метод, конечно, завершился бы. Однако пункт варианта 4 состоит в том, что любой встречный пример недействителен, поскольку в нем указано "любое" исключение.
Опция 3, однако, ограничивает это завершение только тогда, когда генерируется исключение в сигнатуре метода:
- Основной метод должен просто прекратиться, если произойдет
FileNotFoundException
.
Причина варианта 3 имеет большее значение, поскольку код, подобный приведенному ниже, не имеет смысла на практике:
public static void main(String[] args) throws FileNotFoundException {
try {
methodThatThrowsFileNotFoundException();
} catch (FileNotFoundException e) {
// do something to handle this exception
}
}
Не имеет смысла объявлять, что метод генерирует исключение, но улавливает это исключение в методе (если, возможно, вы не перебросили его после выполнения чего-либо, и в этом случае опция 3 все еще выполняется, поскольку метод в конечном итоге заканчивается).
Ответ 5
Только с объявлением main()
невозможно сказать, какой ответ объективно правильный. Любое из утверждений может быть верным, в зависимости от определения метода.
-
Основной метод предназначен для отлова и обработки всех типов исключений.
-
Основной метод предназначен для перехвата и обработки FileNotFoundException
.
Оба приведенных выше утверждения верны для следующего:
public static void main(String[] args) throws FileNotFoundException {
while (true) {
try {
doSomething();
}
catch (Exception e) {}
}
}
Объявленное исключение никогда не вызывается функцией main()
, но это не ошибка; просто бессмысленно и вводит в заблуждение.
-
Основной метод должен просто завершиться, если возникает FileNotFoundException
.
-
Основной метод должен просто завершиться, если произойдет какое-либо исключение.
Оба приведенных выше утверждения верны для следующего:
public static void main(String[] args) throws FileNotFoundException {
try {
doSomething();
}
catch (Exception e) {
return;
}
}
Конечно, мы можем догадаться о намерении вопроса, основываясь на том, что порядочный и разумный программист может намереваться общаться с помощью этой сигнатуры метода. Что было бы, что они предназначены для метода, чтобы бросить FileNotFoundException
, и обязательно обработать другие проверенные Exception
. Мы также можем разумно предположить, что "дескриптор" означает не просто "процесс", а, в частности, что он не будет (re-) генерировать такое исключение.
Эти предположения немедленно исключают # 1 и # 2.
Остается вопрос, включает ли "просто завершение" исключение или только явный return
/System.exit()
. В первом случае оба из # 3 и # 4 все еще могут быть правдой:
public static void main(String[] args) throws FileNotFoundException {
try {
doSomething();
}
catch (FileNotFoundException fnfe) {
throw fnfe;
}
catch (Exception e) {
return;
}
}
В последнем случае ни # 3, ни # 4 не могут быть истинными, в то же время удовлетворяя предположению, что main()
вызовет FileNotFoundException
.
В итоге, варианты не сформулированы хорошо. Если бы мне пришлось выбирать ответ, это был бы № 3, основанный на логике ответа MartinV. Я предполагаю, что слово "должен" в № 3 было неудачным выбором профессора, и что-то вроде "может" было бы лучшим вариантом. Также было бы неплохо использовать более точный язык, чем "просто завершить" (и, возможно, "обработать").
Ответ 6
-
main()
конечном итоге main()
выбрасывает все необработанные исключения, верно? Таким образом, эффективное добавление бросков FileNotFoundException
является излишним.
-
Оператор throws
ничего не говорит о том, как метод обрабатывает исключение. Этот метод main()
может действительно обрабатывать FileNotFoundException
, а затем перезапускать его.
Таким образом, это выражение throws
ничего не указывает на то, как любое исключение перехватывается и обрабатывается. А вопросы 3 и 4 действительны только в том случае, если предположить, что рассматриваемое исключение им не обработано. Без этого предположения вопросы неопределенны. С этим предположением оба 3 и 4 верны!
Правильный ответ - попросить школу вернуть деньги за этот класс - даже через 6,5 лет.
Не могли бы вы отправить эту контактную информацию этого учителя? Я хотел бы поговорить с ними.
Ответ 7
Хотя для этого вопроса уже выбран ответ, я считаю, что правильный ответ на ваш тест - номер 3:
- Основной метод должен просто прекратиться, если происходит FileNotFoundException.
Потому что он говорит, что не должен.
Я имею в виду, что код в методе может поймать любое исключение, как проверенное, так и неконтролируемое, и либо, усвоить, восстановить или изменить его — или он не мог их поймать.
Но если он ловит FileNotFoundException
без его (его) броска, он нарушает свой собственный контракт: любой вызывающий объект не увидит исключение, как указано в сигнатуре метода, потому что метод обрабатывал его (возможно, даже компилятор может жаловаться в этом случае, заявив, что исключение никогда не бросается, но я не уверен здесь).
Я думаю, что ваш средний возраст ставил вопрос о дизайне, а не о конкретной реализации.
Ответ 8
Ответ и 2 и 3.
2. Основной метод предназначен для перехвата и обработки исключения FileNotFoundException. 3. Основной метод должен просто завершиться, если возникает исключение FileNotFoundException.
Но если не удается обработать исключение, даже если оно предназначено для его обработки, и программы завершаются ненормально.
Ключевое слово throws используется, чтобы заставить JVM обрабатывать исключения, которые нам лениво обрабатывать, он успешно компилируется, но показывает исключение во время выполнения (если вы обрабатываете его в методе main, то он компилируется и успешно выполняется).
4. Основной метод должен просто завершиться, если произойдет какое-либо исключение. Не всегда корректно, поскольку возникающие исключения могут обрабатываться в основном методе.
1. Основной метод предназначен для перехвата и обработки всех типов исключений. Это неверно, поскольку JVM не обрабатывает непроверенные исключения.