• ,

level15.lesson09.task04

Подскажите, пожалуйста, почему компилятор ругается?
package com.javarush.test.level15.lesson09.task04;

/* Статики и исключения
В статическом блоке выбросьте RuntimeException
В результате класс не загрузится, и вы увидите сообщение об ошибке вместо значения переменной B

Exception in thread "main" java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:186)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:113)
Caused by: java.lang.RuntimeException:
at com.javarush.test.level15.lesson09.task04.Solution.clinit(Solution.java:22)

Hint: Нужно погуглить причину, если получилось следующее:
java: initializer must be able to complete normally
java: unreachable statement
*/



public class Solution {
    public static int A = 0;

    static {
        //throw an exception here - выбросьте эксепшн тут
        throw new RuntimeException();
    }

    public static int B = 5;

    public static void main(String[] args) {
        System.out.println(B);
    }
}

37 комментариев

Walmar
Кто-нибудь, подскажите пожалуйста)
Sant9Iga
попробуй сделать не
throw new RuntimeException();
, а создать действительно ошибку времени выполнения. A=0 не просто так дано, наверное;)
saul
  • saul
  • 0
  • Комментарий отредактирован 2015-11-13 12:51:00 пользователем saul
Да, некоторые исключения, например ArithmeticException наследуются от RuntimeException, то есть «has-a» RuntimeException.
KoStiG
Долго не мог решить эту элементарную задачу, потому что думал, что окно в Idea с надписью «Неизвестная ошибка» говорит об ошибке в решении.
На сайте прошло с первого раза.
Olexa
Так это и есть ошибка в решении. Убрал «Неизвестная ошибка» поменяв порядок методов.
Класс загружается сверху вниз, поэтому важно, чтобы поле класса обращалось только к уже загруженным другим полям
KoStiG
Странно что решение было защитано через сайт.
А каким должно было быть правильное решение???
Dany
Господа,
Dany
С
throw new RuntimeException();
принимать не хочет, подскажите как ее создать используя A=0.
Sant9Iga
почитай что такое RunTimeException. посмотри на его наследников.
Dany
Чудно! Спасибо! +1
WolfCrazy
Как попробовать ещё одно решение?
Если второй раз пытаться, то возникает ошибка — «Неизвестная ошибка при работе с сервером»
Svejk
Объясните плиз, как я понял «initializer must be able to complete normally» появляется в том случае когда код всегда бросает исключение (нет такого пути при котором этого не произойдет), поэтому мы не можем написать
throw new RuntimeException()
но почему этого не происходит если написать например
int C = 1/A
при А = 0? Или компилятор изначально «не задумывается» о значении А?
eugeniuskh
я так понимаю, что компилятор не «задумывается», а выполняет и все.

о чем эти строки:
Hint: Нужно погуглить причину, если получилось следующее:
java: initializer must be able to complete normally
java: unreachable statement

т.е. если у меня такое не получилось, то и гуглить не нужно?..

Мой код исключение выкинул и все — сервер принял решение. Но у меня некое чувство «нерешонности», т.е. что сервер засчитал неправильный код :(
antonchar
  • antonchar
  • 0
  • Комментарий отредактирован 2014-07-04 21:54:44 пользователем antonchar
Ребята, вы неизвестно что придумываете! В задании же написано:
Нужно погуглить причину, если получилось следующее:
java: initializer must be able to complete normally
java: unreachable statement

при записи просто throw new RuntimeException(); в статике, это и должно вылазить)

1. Берем Гугл
2. Забиваем java: initializer must be able to complete normally
3. Первая же ссылка на stackoverflow.com где эта проблема не только решена, но и растолкована)
mrzzzio
Я долго думал как решить данную задачу. Даю подсказку для таких как я.
Чтобы получить
java: initializer must be able to complete normally
java: unreachable statement

нужно бросить исключение прямо в статике. Что делать дальше отлично описал antonchar .
Чтобы задача засчитывалась на сервере, я сделал так:
— в классе создал метод;
— в этом методе бросил исключение;
— в статике вызвал этот метод.
stannis995
Чет так не работает. Все равно initializer must be able to complete normally
Voronblack
Если честно, не понял ни задания, ни его смысла. Погуглил, зашел на bugs.java.com, скопировал код на который Идея не ругалась и задание засчиталось. Задание заключалось в умении гуглить? Или я где то пропустил лекцию о важности «выбрасивания» исключения в блоке static с ссылкой на дополнительную литературу?
gemuz
Пните… К чему данная задача?
INSIDIUS
  • INSIDIUS
  • 0
  • Комментарий отредактирован 2014-08-31 11:20:41 пользователем INSIDIUS
Задача к тому чтобы понять реакцию анализа компилятора на безоговорочное исключение в блоке инициализации. Он видит что оно неизбежное и пишет «initializer must be able to complete normally» — блок инициализации должен быть завершен нормально. У блока инициализации должен быть и нормальный путь завершения. Обмануть его можно бросив исключение через безоговорочное условие(например если истина то бросить). Анализ при компиляции не идет так далеко, поэтому это прокатит.
firstprime
Два чая этому господину! Теперь я вкурил.
Helga
А у меня приняло с
Exception in thread "main" java.lang.ExceptionInInitializerError
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:259)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:116)
Caused by: java.lang.ArithmeticException: / by zero
	at com.javarush.test.level14.lesson02.task01.Solution.<clinit>(Solution.java:15)
	... 3 more

Что не вполне соответствует условию. Пока я думала, как все же именно Runtime выбросить, задача взяла — и решилась (
freeman_lex
С делением на А (к чему нас подталкивают по условию) бросается арифметическое исключение, которое является наследником, поэтому сервер принимает. Но вывод виходит не такой, как по условию — там нужно получить чистый рантайм. Для этого, как уже писалось выше, нужно бросать новый рантайм с безоговорочным условием.
dimaMJ
а я просто загуглил RuntimeException, посмотрел его наследников и создал ситуацию которая выбрасывает AritmeticException и все )
lisoed
А у меня в статике throw new RuntimeException(); было в try catch завернутое, только catch ловил исключение потомка и RuntimeException пропустил.
Slippa
Сделал условие, если А = 0 то выбрасывает RuntimeException, сервер принял
Dacon
  • Dacon
  • 0
  • Комментарий отредактирован 2015-07-08 14:40:44 пользователем Dacon
if (A = 0) тоже самое что и if(true) в данной задачи, но если рассматривать в общих случаях то второе работает всегда.
valera7979
до меня дошло как нужно сделать когда перевел фразу initializer must be able to complete normally
hauu
Ещё один вариант, косвенно упомянутый на SO:
> Instead you can catch and handle, or wrap the checked exception. (Or using tricks, rethrow it)

Решил через оборачивание в try{} и поимку неверного исключения. Подходят не все неверные! Например если сделать так:

static { { throw new RuntimeException(); } catch (IOException e) {} }

, то не сработает: «Exception IOException is never thrown».
Naissur
Тоже прокатило с эксепшеном, завернутым в try… catch.
Почему такой код проходит, описано в документации.
Invader_Zim
Закинул throw RunTimeException в условие if (true) Все решилось. Странная задача.
balkanskiy
я знаю, что это читерство, но я сделал так ради интереса:

static {
        //throw an exception here - выбросьте эксепшн тут
        try {
        B = A / C;}
        catch (Exception e) {
            throw new RuntimeException();
        }
    }

засчитало.
MaxFuntime
Hint: Нужно погуглить причину, если получилось следующее:
java: initializer must be able to complete normally
java: unreachable statement

У меня такое не получилось. Мне гуглить обязательно?
Кстати, а скопировать в задание то, что мы должны найти, не судьба? Не думал, что нас тут учат гуглению.
Aleksandr78
Да… задача необычная приняло просто деление единицы на а))) без всяких исключений и блоков.
ikratkoe
+1 ))
WhiteSteel
Сделал if условие, при A равным 0, выкинуть эксэпшн.
Интересненько однако
bkozhaev
Ну очень поучительная задачка, я теперь узнал что исключение что бы прошло в статике нужно ставить условие ))
sergentum
я погуглил и решил попробовать сделать так:
if (true)
короче суть обмана компилятора в том что если исключение будет в блоке условного оператора, то значит оно может и не случиться, а значит такой код следует пропустить.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.