• ,

level21.lesson10.task03

/* Найти и исправить ошибку
Найти и исправить ошибку
*/
public class Solution {
    public static void main(String[] args) {

        for (int i = 0; i < 1; i++)
            try {
                new Solution().readFile("ggg");
            } catch (Throwable throwable) {
                System.out.println(i + " " + throwable.getClass().getSimpleName());
            }
    }

    public void readFile(String path) {
        try (BufferedReader br = new BufferedReader(new FileReader(path))) {
            System.out.println(br.readLine());
            dispose();
        } catch (FileNotFoundException ignored) {
            dispose();
        } catch (IOException ignored) {
            dispose();
        } finally {
            System.out.println("finally");
        }
    }

    public void dispose() {
        //pretend to call some method that throws an exception
        throw new RuntimeException("no matter");
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("inside finalize - before throwing");
        dispose();   //исключения игнорируются в finalize
        System.out.println("inside finalize - after throwing");
    }
}


Решить получилось. Но кто-то может объяснить почему это была ошибка?

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

eGarmin
По этой ссылке нашему заданию посвящены пункты 7 и 8:
7. Любые исключения выброшенные в теле метода будут проигнорированы.
8. Надо не забыть в конце метода вызвать super.finalize (). А учитывая предыдущий пункт, сделать это необходимо в блоке finally.
Однако здесь не объяснено почему… Более того, второе предложение пункта 8 на мой взгляд противоречит пункту 7, а не учитывает его. Да и в целом эта статейка похожа на сборник рецептов из какой-то умной книжки. Видно, придется Блоха читать…
levka
  • levka
  • 0
  • Комментарий отредактирован 2014-11-19 14:27:39 пользователем levka
ne ponial
MindIbniM
То есть, finally в try with resources не нужен потому, что последний является автоматически финализируемым?
levka
Это как?
levka
Я не понял логику прогы, что должно быть выведено на экран в правильном исполнении кода?
Vale
  • Vale
  • 0
Присоединяюсь к вопросу!
atatafalker
help!
wildfish
Дайте подсказку
AnatolyAV
Ну подскажите, кто-нибудь)
muxret57
  • muxret57
  • 0
  • Комментарий отредактирован 2014-11-29 22:16:10 пользователем muxret57
Походу задача с багом, Друг смотрел код у него точно такой же код как у меня прошел проверку. До 02.11.2014
EmperioAf
Задача однозначно с багом.
В psvm изменил «ggg» на существующий файл на моём компьютере и больше ничего не менял, и тест прошёл. Я в шоке честно говоря…
aleratorio
Аналогично
Helga
Очень хотелось бы смысл и цели этой задачи увидеть… А то почему-то приняло, а почему и в чем ошибка была — не ясно.
abstract071
Решил так как написано в ссылке из лекции, вот здесь, a именно про «finalizer chaining». Тоже долго думал над задачей. Трудно уловить ее суть.
tevl
Подскажите — Вывод должен быть таким ???
finally
inside finalize - before throwing
inside finalize - after throwing
0 RuntimeException
gemuz
finally
0 RuntimeException

с таким приняло.
Почитал я комменты для задачи и решил, что есть что-то лишнее… убрал catch и тест прошел.
Что дает эта задача?
hotte
я убрал другой блок и тоже приняло =)
видимо, задача должна показать, что не нужен блок finally в конструкции finally-with-resourses
Psich
Я вообще ничего не менял и прошел тест, к чему эта задача непонятно.
Madguy
Честно сказать, задача принимается без каких-либо изменений через браузер. Спасибо всем комментирующим за новую информацию и ссылки про finalize()
linelect
  • linelect
  • 0
  • Комментарий отредактирован 2015-08-11 11:47:03 пользователем linelect
Я так понимаю задача поменялась. Не могу до конца понять суть

<code>package com.javarush.test.level21.lesson10.task03;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/* Нюансы Exceptions
Классы семейства Utilizator должны утилизировать ресурсы не влияя на работу программы, т.е. программа должна отрабатывать одинаково с любым из Utilizator-ов.
На данный момент это не выполняется из-за неправильных реализаций утилизаторов. Исправьте реализацию утилизаторов.
Метод main не участвует в тестировании.
UtilizatorUtil не менять.
Стек трейс не выводить.
*/
public class Solution {
    private Utilizator utilizator;

    public void setUtilizator(Utilizator utilizator) {
        this.utilizator = utilizator;
    }

    public static void main(String[] args) {
        List<String> strings = new ArrayList<>();

        Solution solution = new Solution();
        solution.setUtilizator(new Utilizator());

        Solution solution2 = new Solution();
        solution2.setUtilizator(new SpecificUtilizator());

        strings.addAll(solution.readFileContent("FakeFileName.txt"));
        strings.addAll(solution2.readFileContent("FakeFileName2.txt"));
        System.out.println("Count of strings is " + strings.size());
    }

    public List<String> readFileContent(String path) {
        List<String> strings = new ArrayList<>();
        Charset charset = Charset.forName("UTF-8");
        Path filePath = Paths.get(path);
        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(path)))) {
            String sCurrentLine;
            while ((sCurrentLine = bufferedReader.readLine()) != null) {
                strings.add(sCurrentLine);
            }
        } catch (IOException ignored) {

        } finally {
            utilizator.dispose();
        }
        return strings;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("inside finalize - before throwing");
        utilizator.dispose();   //исключения игнорируются в finalize
        System.out.println("inside finalize - after throwing");
    }

    public static class Utilizator {
        protected final UtilizatorUtil util = new UtilizatorUtil();

        public void dispose() {
            //Utilization IS successful
            util.doNothing();
        }
    }

    public static class SpecificUtilizator extends Utilizator {
        @Override
        public void dispose() {
            util.throwException();
        }
    }

    public static class UtilizatorUtil {
        public void doNothing() {
        }

        public void throwException() {
            throw new RuntimeException("It`s impossible to dispose resources!");
        }

        public void sout(String message) {
            System.out.println(message);
        }
    }
}
</code>
linelect
Что должны делать эти утилизаторы?
linelect
Короче решил ))). Ключевые слова, которые должны вам помочь: «Стек трейс не выводить.»
Но в чем соль задачи так и не понял до конца… Не хватает объяснений после решения.
nOeXit
Намекни куда смотреть, если не сложно, а то что-то смотрю в книгу, вижу фигу -_-
linelect
Я как догнал:
Пишет в задачи «Стек трейс не выводить.» — значит нужно где то поставить try...catch и не выводить стек трейс.
nOeXit
Странна…
Так и делал, ток не там где нужно :) Не совсем ожидаемо, если честно. С тем же успехом можно во втором утилизаторе в dispose поменять метод на doNothing, тоже ведь работать будет :)
linelect
Но не примет задачу)
proud
Не совсем понял задание. Не выводить стек трейс — можно сделать несколько способами:
1. Во втором утилизаторе при вызове dispose() заключить тело в try...catch.
2. В блоке finally обработать возможную ошибку, опять же заключив utilizator.dispose() в try...catch.
И нужно ли вызывать в main метод finalize()?
proud
В общем прошел тест. Вставил два блока try...catch и вызывал finalize().
timon
public List<String> readFileContent(String path) {
        List<String> strings = new ArrayList<>();
        Charset charset = Charset.forName("UTF-8");
        Path filePath = Paths.get(path);
        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(path)))) {
            String sCurrentLine;
            while ((sCurrentLine = bufferedReader.readLine()) != null) {
                strings.add(sCurrentLine);
            }
        } catch (IOException ignored) {
            try {
                finalize();
            }
            catch (Throwable throwable)
            {}
        } finally {
            try {
                utilizator.dispose();
            }
            catch (Exception e)
            {}
        }
        return strings;


стек трейс не выводит, но и finalize до конца не отрабатывает… в чём ошибка?
timon
Уже решил… но задача по моему бредовая…
AlexeyA
Никак не принимает, добавил try...catch в вокруг вызова utilizator.dispose в finally в методе readFileContent и в finalize, все работает. Должен ли вызываться finalize?
boroda
А что конкретно ты изменил, чтобы сервер принял задачу?

Уже 1 день сижу с этой задачей и никак не могу понять.
Adeptius
А я вставил только один блок.
Задача принимается, если стак трейс не выводится вообще.
Странная…
anrud
  • anrud
  • 0
  • Комментарий отредактирован 2015-09-15 19:24:06 пользователем anrud
Уже перебором решать начал (. Не пойму в чем подвох.
Согласно вот этого делаю finalize:
<code>
    @Override
    protected void finalize() throws Throwable {
        try
        {
            System.out.println("inside finalize - before throwing");
            utilizator.dispose();   //исключения игнорируются в finalize
        }catch (RuntimeException ignore){}
        finally
        {
            System.out.println("inside finalize - after throwing");
            super.finalize();
        }
    }
</code>

Далее в public ListreadFileContent(String path) в блоке finally делаю вызов финалайзера
<code>
finally {
               try
              {
                  finalize();
              }
                catch (Throwable e2){}
            }
</code>
Не принимает.
Вариант с отработкой финалайзера только по сработке исключения от utilizator.dispose() в том же блоке finally тоже не отрабатывает. Какой вывод должен быть? Вообще отчет юнит-тестов при ошибке очень помог бы (((.
laz_a_rus
finalize вообще ни причем…
Если просто запустить тот код который приходит с сервера (условие задачи), то будет такой стек трейс, в нем уже есть ответ:
Exception in thread «main» java.lang.RuntimeException: It`s impossible to dispose resources!
at com.javarush.test.level21.lesson10.task03.Solution$UtilizatorUtil.throwException(Solution.java:88)
at com.javarush.test.level21.lesson10.task03.Solution$SpecificUtilizator.dispose(Solution.java:79)
at com.javarush.test.level21.lesson10.task03.Solution.readFileContent(Solution.java:54)
at com.javarush.test.level21.lesson10.task03.Solution.main(Solution.java:38)
anrud
хм…
неожиданно.
Еще бы кто-то логику объяснил этой задачи ).
laz_a_rus
Нужно всего лишь выполнить поставленное задание, ни больше и не меньше.
Классы семейства Utilizator должны утилизировать ресурсы не влияя на работу программы, т.е. программа должна отрабатывать одинаково с любым из Utilizator-ов.
На данный момент это не выполняется из-за неправильных реализаций утилизаторов. Исправьте реализацию утилизаторов.
Неправильная реализация заключается в возбуждении ошибки без блока ее перехвата, соответственно нужно «подавить» любые ошибки, что бы «программа отработала одинаково с любым из Utilizator-ов».
З.Ы. Вообще всегда нужно делать то, что в задании написано, не придумывая себе дополнительной работы :)
anarkiua
Просто нет слов.
prostoaaz
+1 смысл задачи усользнул
Gamakatsu
Нужен такой же JR-Русский переводчик на все задачи.
Grytcyna_Oleg
Спасибо как всегда ) сдал с 1-й попытки)
Legendary
Натолкните еще, если не сложно)
Roman_kh
уже все сказали. Обработай те исключения, которые есть при запуске ))
egomaniac
Один дополнительный момент от меня, пусть вас не смущает неиспользуемвый метод sout класса UtilizatorUtil, забудьте что он там есть. И не думайте вместо стек трейса выводить просто сообщение об ошибке. Есть ошибка или нет, программа должна молчать как партизан :)
Удачи всем!
artur-ant
Благодарность тебе за комент :)
prodigy
Кросаучиг!!!
Roman_kh
ты просто БОГ)
Все оказалось проще, чем я думал :)
bolshakov-as
Ужас. так и не понял смысл этой задачи.
Перебор. добавил try-catch в место где вызывается исключение.
Razor
Аналогично.
olegvasylkov
благодаря коментам сдал. но хотелось бы все же понять смысл переписанной задачи… в чем заключается поучительная часть этого примера?
mrserfr
ну, читайте условие хотя бы внимательно, и будет счастье… вот и поучительная часть
в условии все, что нужно сделать, написано
teajay
требуется только один try-catch… добавить
sfisher
Киньте решение, до сих пор понять не могу, не принимает. Куда именно вставлять этот try-catch?
sfisher
Решил.
Ridje
Я закомментировал метод
public static class SpecificUtilizator extends Utilizator {
        /*@Override
        public void dispose() {
            util.throwException();
        }*/
    }


Условия выполняются, а задача не решается. Что я делаю не так?
SonicBIast
Ну в методе dispose() вызывается метод throwException() — смотри что в нем! А в нем бросается исключение! Значит что надо сделать !?
dimaatkaev
Простите, я не понимаю, создавать метод который кидает исключение, и там же его ловить ничего не выводя? К чему это, в смысле как использовать в работе, или чему научиться? Спасибо!
SonicBIast
  • SonicBIast
  • 0
  • Комментарий отредактирован 2016-02-13 10:08:00 пользователем SonicBIast
В реальной разработке, тебе придется очень много работать с исключениями, т.к. программировать при нормальной ситуации — это нормально, а вот обработать все исключительные ситуации — это чуть сложнее, особенно в бизнес сфере! Нужно будет продумывать что делать если случилось, что то не стандартное! Вот тогда и будешь мутить с исключениями, в общем понимание придет чуть позже! Главное не пренебрегай этой темой, а бросается исключение в методе — ну это особенности языка, в джава все на методах. Это такой уровень абстракции, не могу детальней объяснить, сам ещё плаваю в этом
dimaatkaev
Спасибо!
Retrat
Помог Этот комментарий. После прочтения сразу задачу решил! Спасибо автору
aNikolya
  • aNikolya
  • 0
  • Комментарий отредактирован 2016-02-25 11:21:16 пользователем aNikolya
Может валидатор меняли, но уже истратил около 20 попыток, все пишут, что нужно добавить один try-catch, но не помогает.
finally
{
try
{utilizator.dispose();}
catch (RuntimeException e){}
}
не работает. В finalize() засовывал super.finalize(); в блок finally — тоже нет. Что не так?
Что в результате должно на экран выводится-то?
joyrider
  • joyrider
  • 0
  • Комментарий отредактирован 2016-03-13 19:19:06 пользователем joyrider
Ты не туда добавляешь. В условии сказано исправить утилизаторы, а не solution
deft
о как же я тебя понимаю. чуть с ума не сошел. и super добавлял и private методы делал и final писал, но комментарий по поводу try catch сразу навел на верную мысль. Один из утилизаторов отпадает по условию. Дальше думаю догадаешься.
generatorideas
HINT
1. Запускаем программу
2. Изучаем «выпавший» stack trace
3. Не мудрим! Находим там подсказку, исполняем, то что описывали выше (try… catch)
Все OK! Идем дальше изучать Java в JavaRush!
aNikolya
Спасибо
Pegas
Подскажите в какую строку добавить try-catch. Не могу понять что должна выполнять программа, перечитал все темы по ней. Мой код:
public class Solution {
    private Utilizator utilizator;

    public void setUtilizator(Utilizator utilizator) {
        this.utilizator = utilizator;
    }

    public static void main(String[] args) {
        List<String> strings = new ArrayList<>();

        Solution solution = new Solution();
        solution.setUtilizator(new Utilizator());

        Solution solution2 = new Solution();
        solution2.setUtilizator(new SpecificUtilizator());

        strings.addAll(solution.readFileContent("FakeFileName.txt"));
        strings.addAll(solution2.readFileContent("FakeFileName2.txt"));
        System.out.println("Count of strings is " + strings.size());
    }

    public List<String> readFileContent(String path) {
        List<String> strings = new ArrayList<>();
        Charset charset = Charset.forName("UTF-8");
        Path filePath = Paths.get(path);
        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(path)))) {
            String sCurrentLine;
            while ((sCurrentLine = bufferedReader.readLine()) != null) {
                strings.add(sCurrentLine);
            }
        } catch (IOException ignored) {

        } finally {
            try{
                utilizator.dispose();
            }
            catch(Exception e) {

            }
        }
        return strings;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println("inside finalize - before throwing");
        utilizator.dispose();   //исключения игнорируются в finalize
        System.out.println("inside finalize - after throwing");
    }

    public static class Utilizator {
        protected final UtilizatorUtil util = new UtilizatorUtil();

        public void dispose() {
            //Utilization IS successful
            util.doNothing();
        }
    }

    public static class SpecificUtilizator extends Utilizator {
        @Override
        public void dispose() {
            util.throwException();
        }
    }

    public static class UtilizatorUtil {
        public void doNothing() {
        }

        public void throwException() {
            throw new RuntimeException("It`s impossible to dispose resources!");
        }

        public void sout(String message) {
            System.out.println(message);
        }
    }
}
Pegas
В строке
System.out.println("Count of strings is " + strings.size());
чему должен быть равен strings.size(), 2?
Grif
  • Grif
  • 0
  • Комментарий отредактирован 2016-05-20 15:26:38 пользователем Grif
Даааа :) Задача просто нечто :) Единственная её польза — это практика чтения чужого кода :)
Tigran
  • Tigran
  • 0
  • Комментарий отредактирован 2016-07-15 11:48:28 пользователем Tigran
Задача из серии:
— «Нет времени объяснять! Просто сделай что я хочу!»
— «А что ты хочешь?»
— «Хочу, чтобы все было хорошо, неужели непонятно???»
burduk
  • burduk
  • 0
  • Комментарий отредактирован 2016-07-15 23:11:21 пользователем burduk
del
Pavel255
Вот же ж, а если удалить во втором классе утилизатора метод dispose() или сделать его таким же, как и в первом классе, то эти варианты не принимаются, хотя работает аналогично.
Первые две попытки ушли на это, хотя и сомневался, ну не могли наверное сделать так просто)
Ключевая фраза задания — Стек трейс не выводить.
malei_ka
И еще одна подсказка.
Смотрите куда именно вы ставите обработку исключения, ведь исключения пробрасываются через несколько методов. 1 лишний метод может повлиять на проверку
ILIA
  • ILIA
  • 0
Мда… сказанно, что метод мейн в тестировании не участвует, но у меня он участвовал.
Вместо дефолтного
strings.addAll(solution.readFileContent("FakeFileName.txt"));

у меня было
strings.addAll(solution2.readFileContent(args[1]));
naatsms
Это не значит, что main участвует. Не морочь людям головы, можно вообще убрать из решения метод main и все равно сдать задачу.
NoiZze
Задачу решил с помощью подсказок и логики, но не понял что к чему… Дайте ссылку на доп материал или объясните кто-нить.
Archie369
Для тех кто запутался, в условии просят дословно: подавить выброс исключения одним из утилизаторов.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.