Свежие записи из блогов Widowmaker1984

Widowmaker1984, блог «Дом на краю кладбища»

Я увольняюсь

В пятницу подписали заявление, поэтому "отрабатывать" две недели буду до конца июня. Немного странно уходить из фирмы, где проработал больше восьми лет. Но в целом пора уже.

 

В прошлый раз с работы я уходил еще в Кургане. Тогда как раз был кризис, и людей "оптимизировали" на ура. Я почему-то оказался в половине, которую не уволили.

 

Завод, где мне посчастливилось работать программистом, отличался от прочих уникальной по меркам времени успешностью: в нем все еще платили зарплату. Только изменилась часть стенгазеты под названием "о премировании". Традиционно там писали, как какого-нибудь проштрафившегося рабочего оставили без премии, но теперь лишать уже было нечего. Поэтому раздел превратился в перечисление всевозможных прегрешений. "Мастер Иванов уронил свидетеля в станок".

 

Поскольку работа "оптимизированных" сотрудников падала на еще не уволенных, стало ее вскоре очень и очень много. Я задерживался, оставался по выходным, и довольно успешно доработался до того, что стал подмечать, как неудачно расположены в моем городе лавочки. Так как каждые сколько-то там шагов начинало болеть в груди. Приходилось садиться и отдыхать.

 

В общем, как-то раз я обратился к замначальнице с вопросом о том, как правильно оформлять заявление об уходе.

 

— Александр Сергеевич, — она всегда называла меня именно так, потому что "Саша" у нас в отделе уже был, а мне требовался уникальный идентификатор, — вас никто не собирается увольнять.

— Нет, вы не поняли, я сам ухожу.

— А, ну тогда ладно.

 

Было это в конце июня, почти девять лет назад. Вскоре мне исполнилось 25, и я с концами уехал в Москву.

Widowmaker1984, блог «Java для собеседований»

Оглавление блога со ссылками

Часть 1. Типы данных, переменные, операторы, циклы, массивы
скрытый текстВопрос 1. Сколько ключевых слов зарезервировано языком, что это за слова, какие из них не используются?
Вопрос 2. Из каких символов может состоять имя переменной (корректный идентификатор)?
Вопрос 3. Что значит слово «инициализация»?
Вопрос 4.1. На какие основные группы можно поделить типы данных? (про примитивные типы)
Вопрос 4.2. На какие основные группы можно поделить типы данных? (про составные типы)
Вопрос 5. Какие примитивные типы вы знаете? Назовите размерность в байтах для каждого типа.
Вопрос 6. Что вы знаете о преобразовании примитивных типов данных, есть ли потеря данных, можно ли преобразовать логический тип?
Вопрос 7. Какими значениями инициализируются переменные по умолчанию?
Вопрос 8. Как передается значение переменной (по ссылке/значению)?
Вопрос 9. Что вы знаете о функции main, какие обязательные условия ее определения?
Вопрос 10. Какие логические операции и операторы вы знаете?
Вопрос 11. В чем разница краткой и полной схемы записи логических операторов?
Вопрос 12. Что такое таблица истинности?
Вопрос 13. Что такое тернарный оператор выбора?
Вопрос 14.1. Какие унарные операции вы знаете?
Вопрос 14.2. Про операторы присвоения, отношения и арифметические бинарные операции.
Вопрос 15. Какая арифметическая операция выполняется при побитовом сдвиге вправо/влево?
Вопрос 16. Какова роль и правила написания оператора выбора?
Вопрос 17. Какие циклы вы знаете, в чем их отличия?
Вопрос 18. Что такое «итерация цикла»?
Вопрос 19. Какие параметры имеет цикл for, можно ли их не задать?
Вопрос 20. Какой оператор используется для немедленной остановки цикла?
Вопрос 21. Какой оператор используется для перехода к следующей итерации цикла?
Вопрос 22. Что такое массив?
Вопрос 23. Какие виды массивов вы знаете?
Вопрос 24. Что вы знаете о классах оболочках?
Вопрос 25. Что такое автоупаковка (boxing/unboxing)?

Часть 2. Объектно-ориентированное программирование
скрытый текстВопрос 26. Назовите принципы ООП и расскажите о каждом.
Вопрос 27. Дайте определение понятию «класс»
Вопрос 28. Что такое поле/атрибут класса?
Вопрос 29. Как правильно организовать доступ к полям класса?
Вопрос 30. Дайте определение понятию «конструктор».
Вопрос 31. Чем отличаются конструкторы по-умолчанию, копирования и конструктор с параметрами?
Вопрос 32. Какие модификации уровня доступа вы знаете, расскажите про каждый из них.
Вопрос 33. Расскажите об особенностях класса с единственным закрытым (private) конструктором.
Вопрос 34. О чем говорят ключевые слова «this», «super», где и как их можно использовать?
Вопрос 35. Дайте определение понятию «метод».
Вопрос 36. Что такое сигнатура метода?
Вопрос 37. Какие методы называются перегруженными?
Вопрос 38. Могут ли нестатические методы перегрузить статические?
Вопрос 39. Расскажите о переопределение методов.
Вопрос 40. Может ли метод принимать разное количество параметров (аргументы переменной длины)?
Вопрос 41. Можно ли сузить уровень доступа/тип возвращаемого значения при переопределении метода?
Вопрос 42. Как получить доступ к переопределенным методам родительского класса?
Вопрос 43. Какие преобразования называются нисходящими и восходящими?
Вопрос 44. Чем отличается переопределение от перегрузки?
Вопрос 45. Где можно инициаилизировать статические/нестатические поля?
Вопрос 46. Зачем нужен оператор instanceof?
Вопрос 47. Зачем нужны и какие бывают блоки инициализации?
Вопрос 48. Каков порядок вызова конструкторов и блоков инициализации двух классов: потомка и его предка?
Вопрос 49. Где и для чего используется модификатор abstract?
Вопрос 50. Можно ли объявить метод абстрактным и статическим одновременно?
Вопрос 51. Что означает ключевое поле static?
Вопрос 52. К каким конструкциям Java применим модификатор static?
Вопрос 53. Что будет, если в static блоке кода возникнет исключительная ситуация?
Вопрос 54. Можно ли перегрузить static метод?
Вопрос 55. Что такое статический класс, какие особенности его использования?
Вопрос 56. Какие особенности инициализации final static переменных?
Вопрос 57. Как влияет модификатор static на класс/метод/поле?
Вопрос 58. О чем говорит ключевое слово final?
Вопрос 59. Дайте определение понятию «интерфейс».
Вопрос 60. Какие модификаторы по умолчанию имеют поля и методы интерфейсов?
Вопрос 61. Почему нельзя объявить метод интерфейса с модификатором final или static?
Вопрос 62. Какие типы классов бывают в java (вложенные… и.т.д.)
Вопрос 63. Что вы знаете о вложенных классах, зачем они используются? Классификация, варианты использования, о нарушении инкапсуляции.
Вопрос 64. Каким образом из вложенного класса получить доступ к полю внешнего класса?
Вопрос 65. Какие особенности создания вложенных классов: простых и статических.
Вопрос 66. В чем разница вложенных и внутренних классов?
Вопрос 67. Какие классы называются анонимными?
Вопрос 68. Каким образом можно обратиться к локальной переменной метода из анонимного класса, объявленного в теле этого метода? Есть ли какие-нибудь ограничения для такой переменной?
Вопрос 69. Как связан любой пользовательский класс с классом Object?
Вопрос 70. Расскажите про каждый из методов класса Object.
Вопрос 71. Что такое метод equals(). Чем он отличается от операции ==.
Вопрос 72. Если вы хотите переопределить equals(), какие условия должны удовлетворяться для переопределенного метода?
Вопрос 73. Если equals() переопределен, есть ли какие-либо другие методы, которые следует переопределить?
Вопрос 74. В чем особенность работы методов hashCode и equals? Каким образом реализованы методы hashCode и equals в классе Object? Какие правила и соглашения существуют для реализации этих методов? Когда они применяются?
Вопрос 75. Какой метод возвращает строковое представление объекта?
Вопрос 76. Что будет, если переопределить equals не переопределяя hashCode? Какие могут возникнуть проблемы?
Вопрос 77. Есть ли какие-либо рекомендации о том, какие поля следует использовать при подсчете hashCode?
Вопрос 78. Как вы думаете, будут ли какие-то проблемы, если у объекта, который используется в качестве ключа в hashMap изменится поле, которое участвует в определении hashCode?
Вопрос 79. Чем отличается абстрактный класс о интерфейса, в каких случаях что вы будете использовать?
Вопрос 80. Можно ли получить доступ к private переменным класса и если да, то каким образом?
Вопрос 81. Модификаторы. Назначение и варианты использования.
Вопрос 82. Что такое volatile и transient?
Вопрос 83. Контексты использования модификаторов (класс/поле/метод).
Вопрос 84. Какой из модификаторов более строгий: protected или package-private?
Вопрос 85. Расширение модификаторов при наследовании, переопределение и сокрытие методов. Если у класса-родителя есть метод, объявленный как private, может ли наследник расширить его видимость? А если protected? А сузить видимость?
Вопрос 86. Модификатор abstract и final для классов/методов.
Вопрос 87. Имеет ли смысл объявлять метод private final?
Вопрос 88. Какие особенности инициализации final переменных?
Вопрос 89. Что будет, если единственный конструктор класса объявлен как final?
Вопрос 91. Что такое finalize? Зачем он нужен? Что Вы можете рассказать о сборщике мусора и алгоритмах его работы.
Вопрос 92. Почему метод clone объявлен как protected? Что необходимо для реализации клонирования?

Часть 3. Исключения
скрытый текстВопрос 98. Дайте определение понятию «исключение».
Вопрос 99. Какова иерархия исключений?
Вопрос 100. Можно/нужно ли обрабатывать ошибки JVM?
Вопрос 101. Какие существуют способы обработки исключений?
Вопрос 102. О чем говорит ключевое слово throws?
Вопрос 103. В чем особенность блока finally? Всегда ли он исполняется?
Вопрос 104. Может ли не быть ни одного блока catch при отлавливании исключений?
Вопрос 105. Могли бы вы придумать ситуацию, когда блок finally не будет выполнен?
Вопрос 106. Может ли один блок catch отлавливать несколько исключений (с одной и разных веток наследований)?
Вопрос 107. Что вы знаете об обрабатываемых и не обрабатываемых (catched/uncatched) исключениях?
Вопрос 108. В чем особенность RuntimeException?
Вопрос 109. Как написать собственное («пользовательское») исключение? Какими мотивами вы будете руководствоваться при выборе типа исключения: checked/unchecked?
Вопрос 110. Какой оператор позволяет принудительно выбросить исключение?
Вопрос 111. Есть ли дополнительные условия к методу, который потенциально может выбросить исключение?
Вопрос 112. Может ли метод main выбросить исключение вовне и если да, то где будет происходить обработка данного исключения?
Вопрос 113. Если оператор return содержится и в блоке catch и в finally, какой из них «главнее»?
Вопрос 116. Что такое Error? В каком случае используется Error. Приведите пример Error’а.
Вопрос 117. Какая конструкция используется в Java для обработки исключений?
Вопрос 118. Возможно ли использование блока try-finally (без catch)?
Вопрос 119. Предположим, есть блок try-finally. В блоке try возникло исключение и выполнение переместилось в блок finally. В блоке finally тоже возникло исключение. Какое из двух исключений “выпадет” из блока try-finally? Что случится со вторым исключением?

Widowmaker1984, блог «Java для собеседований»

Вопросы 101-106, 109-113, 117-119 (обработка исключений)

"Какие существуют способы обработки исключений?"
"О чем говорит ключевое слово throws?"
"В чем особенность блока finally? Всегда ли он исполняется?"
скрытый текст"Может ли не быть ни одного блока catch при отлавливании исключений?"
"Могли бы вы придумать ситуацию, когда блок finally не будет выполнен?"
"Может ли один блок catch отлавливать несколько исключений (с одной и разных веток наследований)?"
"Как написать собственное («пользовательское») исключение? Какими мотивами вы будете руководствоваться при выборе типа исключения: checked/unchecked?"
"Какой оператор позволяет принудительно выбросить исключение?"
"Есть ли дополнительные условия к методу, который потенциально может выбросить исключение?"
"Может ли метод main выбросить исключение вовне и если да, то где будет происходить обработка данного исключения?"
"Если оператор return содержится и в блоке catch и в finally, какой из них «главнее»?"
"Какая конструкция используется в Java для обработки исключений?"
"Возможно ли использование блока try-finally (без catch)?"

"Предположим, есть блок try-finally. В блоке try возникло исключение и выполнение переместилось в блок finally. В блоке finally тоже возникло исключение. Какое из двух исключений “выпадет” из блока try-finally? Что случится со вторым исключением?"


1. В Java есть пять ключевых слов для работы с исключениями:
try - данное ключевое слово используется для отметки начала блока кода, который потенциально может привести к ошибке.
catch - ключевое слово для отметки начала блока кода, предназначенного для перехвата и обработки исключений.
finally - ключевое слово для отметки начала блока кода, которое является дополнительным. Этот блок помещается после последнего блока 'catch'. Управление обычно передаётся в блок 'finally' в любом случае.
throw - служит для генерации исключений.
throws - ключевое слово, которое прописывается в сигнатуре метода, и обозначающее что метод потенциально может выбросить исключение с указанным типом.

скрытый текст2. Когда возникает исключительное состояние, создается объект одного из подклассов Exception. По его типу становится яснее, какая именно ошибка возникла при выполнении программы. Созданный объект пересылается в метод, обрабатывающий данный тип исключительной ситуации.

2.1. Для задания блока программного кода, который требуется защитить от исключений, используется ключевое слово try. Сразу же после try-блока помещается блок catch, задающий тип исключения которое вы хотите обрабатывать. Целью большинства хорошо сконструированных catch-разделов должна быть обработка возникшей исключительной ситуации и приведение переменных программы в некоторое разумное состояние — такое, чтобы программу можно было продолжить так, будто никакой ошибки и не было.

2.1.1. Общий вид конструкции для «поимки» исключительной ситуации выглядит следующим образом:

try{
//здесь код, который потенциально может привести к ошибке
}
catch(SomeException e ){ //в скобках указывается класс конкретной ожидаемой ошибки
//здесь описываются действия, направленные на обработку исключений
}
finally{
//выполняется в любом случае ( блок finally не обязателен)
}

скрытый текст2.2. В некоторых случаях один и тот же блок программного кода может возбуждать исключения различных типов. Для того, чтобы обрабатывать подобные ситуации, Java позволяет использовать для одного try-блока любое количество catch-разделов. Наиболее специализированные классы исключений должны идти первыми, поскольку ни один подкласс не будет достигнут, если поставить его после суперкласса.

2.3. Операторы try можно вкладывать друг в друга аналогично тому, как можно создавать вложенные области видимости переменных. Если у оператора try низкого уровня нет раздела catch, соответствующего возбужденному исключению, стек будет развернут на одну ступень выше, и в поисках подходящего обработчика будут проверены разделы catch внешнего оператора try.

2.4. В Java 7 стала доступна новая конструкция, с помощью которой можно перехватывать несколько исключений одним блоком catch. Пример:

catch( IOException | SQLException ex )

2.5. Конструкция try-with-resources, также именуемая "автоматическое управление ресурсами", представляет новый механизм обработки исключений, который был представлен в Java 7 , осуществляя автоматическое закрытие всех ресурсов, используемых в рамках блока try/catch.

2.5.1. Чтобы воспользоваться данным оператором, нужно разместить заданные ресурсы в круглых скобках, после чего созданный ресурс будет автоматически закрыт по окончании блока.

2.5.2. При работе с конструкцией try-with-resources следует принимать во внимание следующие нюансы:
- С целью использования конструкции try-with-resources следует реализовать интерфейс AutoCloseable, после чего соответствующий метод close() будет вызван автоматически во время выполнения.
- В конструкции try-with-resources возможно указание одного и более классов.
- При указании нескольких классов в блоке try конструкции try-with-resources, закрытие данных классов будет производиться в обратном порядке.
- За исключением внесения ресурсов в скобки, прочие элементы аналогичны нормальному блоку try/catch в составе блока try.

3. Исключения могут возбуждаться и «вруч­ную» для того, чтобы сообщить о некоторых нештатных ситуациях.

3.1. Оператор throw используется для возбуждения исключения «вруч­ную». Для того, чтобы сделать это, нужно иметь объект подкласса клас­са Throwable, который можно либо получить как параметр оператора catch, либо создать с помощью оператора new. Ниже приведена общая форма оператора throw:

throw [ОбъектТипаThrowable];

3.1.1. При достижении этого оператора нормальное выполнение кода немедленно прекращается, так что следующий за ним оператор не выполняется. Ближайший окружающий блок try проверяется на наличие соответствующего возбужденному исключению обработчика catch. Если такой отыщется, управление передается ему. Если нет, проверяется следующий из вложенных операторов try, и так до тех пор пока либо не будет найден подходящий раздел catch, либо обработчик исключений исполняющий системы Java не остановит программу, выведя при этом состояние стека вызовов.

3.2. Только подклассы класса Throwable могут быть возбуждены или перехвачены. Простые типы (int, char и т.п.), а также классы, не являющиеся подклассами Throwable (например, String и Object) использоваться в качестве исключений не могут. Наиболее общий путь для использования исключений — создание своих собственных подклассов класса Ex­ception.

3.2.1. При создании собственных классов исключений следует принимать во внимание следующие аспекты:
- Все исключения должны быть дочерними элементами Throwable.
- Если планируете создать контролируемое исключение, следует расширить класс Exception.
- Если хотите создать исключение на этапе выполнения, следует расширить класс RuntimeException.

4. Обработка исключения может быть произведена с помощью операторов try…catch, либо "проброшена" внешней части программы. Т.е. метод может передавать возникшие в нём исключения выше по иерархии вызовов, сам его не обрабатывая. Если исключение обрабатывается в методе, оно не обязано "пробрасываться", и наоборот.

4.1. Если метод способен возбуждать исключения, которые он сам не обрабатывает, он должен объявить о таком поведении, чтобы вызывающие методы могли защитить себя от этих исключений. Для задания списка исключений, которые могут возбуждаться методом, используется ключевое слово throws. Если метод в явном виде (т.е. с помощью оператора throw) возбуждает исключение соответствующего класса, тип класса исключений должен быть указан в операторе throws в объявлении этого метода.

4.2. С учетом этого наш прежний синтаксис определения метода должен быть расширен следующим образом:
тип имя_метода(список аргументов) throws список_исключений

4.2. Метод может "пробрасывать" исключения, которые в нем реально не падают (например, на будущее) или пробрасывать исключения более "широких" классов, чем в нем возможны.

4.4. Метод public static void main( String[] args ) - обычный метод, и кроме того, что вызывается виртуальной машиной для начала выполнения программы, может быть вызван из любого другого кода. На него распространяются обычные правила указания выбрасываемых проверяемых исключений (checked exceptions) после throws.

4.4.1. Поэтому если код в main может вызвать проверяемые исключения (например, вы читаете файл с помощью Files.lines() который может бросить IOException), компилятор заставит вас либо поймать исключение в try-catch, либо указать его в throws.

4.4.1.1. Не пойманные исключения ловит экземпляр java.lang.Thread.UncaughtExceptionHandler. У каждого Thread может быть свой обработчик (задается через setUncaughtExceptionHandler; обрабатывает исключения, брошенные в этом процессе), либо можно установить обработчик по-умолчанию, через Thread.setDefaultUncaughtExceptionHandler, который и будет обрабатывать все необработанные исключения.

5. Иногда требуется гарантировать, что определенный участок кода будет выполняться независимо от того, какие исключения были возбуждены и перехвачены. Для создания такого участка кода используется ключевое слово finally. Он очень удобен для закрытия файлов и освобождения любых других ресурсов, захваченных для временного использования в начале выполнения метода.

5.1. Даже в случаях, когда в методе нет соответствующего возбужденному исключению раздела catch, блок finally будет выполнен до того, как управление перейдет к операторам, следующим за разделом try.

5.2. Следует помнить, что:
- Выражение catch не может существовать без оператора try.
- При наличии блока try/catch, выражение finally не является обязательным.
- Блок try не может существовать при отсутствии выражения catch либо выражения finally.
- Существование какого-либо кода в промежутке между блоками try, catch, finally является невозможным.

5.2.1. Запись без catch допустима, если имеется связка try... finally . Но смысла в подобной записи немного.

5.3. Блок finally выполняется не всегда, например если в блоке try вызывать System.exit(0), то finally недостижим, так как происходит системный выход из программы. Общими словами: когда JVM умирает, ей уже не до finally.

5.4. Если в блоке try есть return, блок finally все равно будет вызван. А если данный блок содержит уже свой return, то именно он в итоге и будет задавать возвращаемое значение. В этом смысле данный return "главнее".

5.5. Аналогично, если в обоих блоках упадут исключения, то исключение в finally «проглотит» исключение в try. Чтобы не "потерять" исключение, его можно обработать в блоке try.

Widowmaker1984, блог «Дом на краю кладбища»

Антоний Блум. "Без записок"

Самая запомнившаяся цитата:

 

"Когда мне было лет четырнадцать, у нас впервые оказалось помещение, где мы могли жить все втроем: бабушка, мама и я. И в первый раз в жизни с тех пор, как кончилось раннее детство, когда мы ехали из Персии, я вдруг пережил какую-то возможность счастья; до сих пор, когда я вижу сны блаженного счастья, они происходят в этой квартире. В течение двух-трех месяцев это было просто безоблачное блаженство.

 

И вдруг случилась совершенно для меня неожиданная вещь: я испугался счастья. Вдруг мне представилось, что счастье страшнее того очень тяжелого, что было раньше, потому что когда жизнь была сплошной борьбой, самозащитой или попыткой уцелеть, в жизни была цель: надо было уцелеть вот сейчас, надо было обеспечить возможность уцелеть немножко позже, надо было знать, где переночуешь, надо было знать, как достать что-нибудь, что можно съесть, — вот в таком порядке.

 

А когда вдруг оказалось, что всей этой ежеминутной борьбы нет, получилось, что жизнь совершенно опустела, потому что можно ли строить всю жизнь на том, что бабушка, мама и я друг друга любим - но бесцельно? Что нет никакой глубины в этом, что нет никакой вечности, никакого будущего, что вся жизнь в плену двух измерений: времени и пространства, — а глубины в ней нет; может быть, какая-то толщина есть, она может какие-нибудь сантиметры собой представлять, но ничего другого, дно сразу.

 

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

Скрытое содержимое

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

Widowmaker1984, блог «Дом на краю кладбища»

"Постигая такое, что не хочется жить"

Повторяю программирование с помощью гугла. Из статьи про исключения узнаю следующее:

1. "При выполнении программ бывает, что случаются исключения."
(не без этого)
2. "Исключения это объекты, и они делятся на два типа: во-первых, исключения (Exception), а во-вторых ошибки (Error)."
(все страньше и страньше)
3. "Exception — это такие ошибки, которые..."
(недолго музыка играла)

Про то, чем отличаются вложенные классы от внутренних:

1. "Внутренние классы делятся на четыре типа."
(да, классификации наше все)
2. "Первый тип — это классы вложенные (static nested classes)."
(верю, почему нет)
3. "Но это не настоящие внутренние классы."
(и они, наверное, делают неправильный мед)

скрытый текстВообще, про классы я натыкался на четыре версии. Приятно, когда есть выбор:

1. Вложенные классы — подвид внутренних.
2. Внутренние классы — подвид вложенных.
3. Это два разные типа классов.
4. Это синонимы.

Лучше про блок finally почитаю. Там все должно быть просто. Открываю список ответов, там: "Код в блоке finally будет выполнен всегда."

Последнее слово выделено жирным шрифтом. Двумя абзацами ниже:

"Блок finally выполняется не всегда, например... "

Widowmaker1984, блог «Java для собеседований»

Вопросы 98, 99, 100, 107, 108, 116 (исключения и их иерархия)

"Дайте определение понятию «исключение»."
"Какова иерархия исключений?"
"Можно/нужно ли обрабатывать ошибки JVM?"
"Что вы знаете об обрабатываемых и не обрабатываемых (catched/uncatched) исключениях?"
"В чем особенность RuntimeException?"
"Что такое Error? В каком случае используется Error. Приведите пример Error’а."


1. Исключениями или исключительными ситуациями (состояниями) называются ошибки, возникшие в программе во время её работы. В случае их возникновения она может завершиться в аварийном режиме. Поэтому исключительные ситуации рекомендуется обрабатывать.

1.1. Исключения могут возникать во многих случаях, например:
- Пользователь ввел некорректные данные.
- Файл, к которому обращается программа, не найден.
- Сетевое соединение с сервером было утеряно во время передачи данных.

1.2. Обработка исключительных ситуаций (exception handling) — механизм языков программирования, предназначенный для описания реакции программы на ошибки времени выполнения и другие возможные проблемы (исключения), которые могут возникнуть и приводят к невозможности (либо бессмысленности) дальнейшей отработки программой её базового алгоритма.

скрытый текст2. Все исключения в Java являются объектами. Поэтому они могут порождаться не только автоматически при возникновении исключительной ситуации, но и создаваться самим разработчиком.

2.1. Исключения делятся на несколько классов, но все они имеют общего предка — класс Throwable. Его потомками являются подклассы Exception и Error.

2.1.1. Собственно "исключения" (Exceptions) являются результатом проблем в программе, которые в принципе решаемы и предсказуемы. Например, произошло деление на ноль в целых числах.

2.1.2. "Ошибки" (Errors) представляют собой более серьёзные проблемы, которые, согласно спецификации Java, не следует пытаться обрабатывать в собственной программе, поскольку они связаны с проблемами уровня JVM. Например, исключения такого рода возникают, если закончилась память, доступная виртуальной машине. Программа всё равно не сможет обеспечить дополнительную память для JVM.

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

2.1.2.2. Подклассы Error:
- ThreadDeath — вызывается при неожиданной остановке потока посредством метода Thread.stop().
- StackOverflowError — ошибка переполнение стека. Часто возникает в рекурсивных функциях из-за неправильного условия выхода.
- OutOfMemoryError — ошибка переполнения памяти.

2.2. В Java все исключения делятся на два типа:
- неконтролируемые исключения (unchecked), к которым относятся:
1) ошибки (Errors);
2) исключения времени выполнения (RuntimeExceptions, потомок класса Exception);
- контролируемые исключения (checked), которые можно и нужно обрабатывать в программе, к этому типу относятся все потомки класса Exception , кроме RuntimeException).

2.2.1. Основное различие в том, что обработка checked исключения проверяются на этапе компиляции. Обработка unchecked исключения происходит на этапе выполнения. Пример unchecked исключения - NullPointerException, checked исключения - IOException.

2.2.1.1. Почему не все исключения являются проверяемыми? Дело в том, что если проверять каждое место, где теоретически может быть ошибка, код сильно разрастется, станет плохо читаемым. Например в любом месте, где происходит деление чисел, нужно было бы проверять на ArithmeticException, потому что возможно деление на ноль. Эту опцию (отлавливать не проверяемые исключения) создатели языка оставили на усмотрение программиста.

2.2.2. Неконтролируемые исключения не требуют обязательной обработки, однако, при желании, можно обрабатывать исключения класса RuntimeException.

2.2.3. Класс RuntimeException extends Exception — базовый класс для ошибок во время выполнения. Относится к unchecked-исключениям. Это суперкласс, исключения которого могут быть выброшены во время нормальной работы JVM.

2.2.3.1. Подклассы RuntimeException:
- IndexOutOfBoundsException — выбрасывается, когда индекс некоторого элемента в структуре данных(массив/коллекция) не попадает в диапазон имеющихся индексов.
- NullPointerException - ссылка на объект, к которому вы обращаетесь хранит null.
- ClassCastException – Ошибка приведения типов. Всякий раз при приведении типов делается проверка на возможность приведения (проверка осуществляется с помощью instanceof.
- ArithmeticException - бросается когда выполняются недопустимые арифметические операции, например деление на ноль.

3. Список важных методов, доступных в классе Throwable:
- public String getMessage() Возврат подробного сообщения о произошедшем исключении. Инициализация данного сообщения производится в конструкторе Throwable.
- public Throwable getCause() Возврат причины исключения, представленной объектом Throwable.
- public String toString() Возврат имени класса, соединенного с результатом getMessage().
- public String printStackTrace() Выведение результата toString() совместно с трассировкой стека в System.err, поток вывода ошибок.
- public StackTraceElement [] getStackTrace() Возврат массива, содержащего каждый элемент в трассировке стека. Элемент с номером 0 представляет вершину стека вызовов, последний элемент массива отображает метод на дне стека вызовов.
- public Throwable fillInStackTrace() Заполняет трассировку стека данного объекта Throwable текущей трассировкой стека, дополняя какую-либо предшествующую информацию в трассировке стека.

Widowmaker1984, блог «Java для собеседований»

Вопрос 92 (про клонирование объектов)

"Почему метод clone объявлен как protected? Что необходимо для реализации клонирования?"

1. Иногда необходимо получить копию объекта, которая не зависела бы от оригинала и с которой можно было бы производить манипуляции, при этом не изменяя оригинал. При обыкновенном присваивание объектов (obj1 = obj2;) передаются ссылки на объект. В итоге два экземпляра ссылаются на один объект, и изменение одного приведет к изменению другого. В данном случае, на помощь придет интерфейс Cloneable и метод clone() класса Object.

1.1. Метод clone() класса Object создает и возвращает копию объекта с такими же значениями полей. Если копируемый объект содержит ссылки на другие объекты, то ссылки будут скопированы, но дубликаты тех объектов не создаются. Это называется "поверхностным" (shallow) клонированием. Оно работает корректно (по соглашению, метод clone() должен возвращать объект независимый от клонируемого объекта), если объект содержит только примитивные поля или ссылки на неизменяемые объекты.

1.2. Обратите внимание, что метод clone нативный и делает нечто, что иными способами сделать нельзя, а именно создает копию объекта без вызова конструктора.

2. Метод clone() может выбрасывать исключение CloneNotSupportedException. Данное исключение возникает в случае, когда клонируемый класс не имеет реализации интерфейса Cloneable. Интерфейс Cloneable не реализует ни одного метода. Он является всего лишь маркером, говорящим, что данный класс реализует клонирование объекта.

2.1. Сам Object не реализует Clonable, а метод объявлен, как protected. Поэтому он доступен только при наследовании от объекта. Но это не является проблемой, потому как любой класс, является потомком класса Object. При переопределении метод clone() необходимо расширить до public.

2.2.1. Пример расширения метода clone().
public User clone() throws CloneNotSupportedException {
return (User)super.clone();
}

скрытый текст2.3. Перед дизайнерами языка стояла следующая задача: предоставить функциональность клонирования без вызова конструктора пользователям, но оставить за ними право выбора, можно ли подобную операцию проводить над их классами. Последнее было реализовано с помощью маркерного интерфейса (поскольку аннотаций тогда еще не было), а сам метод решили положить в базовый класс, чтобы при его переопределении автор класса мог в случае необходимости (наличия ссылок на изменяемые объекты) доделать поверхностное копирование до более глубокого.

3. Перед тем как объявлять свой класс как Cloneable, следует внимательно проанализировать его структуру, и определить какие поля нужно проинициализировать после выполнения super.clone().

3.1. Из-за того, что интерфейс Cloneable не имеет публичного метода clone(), к этой операции не получается применить полиморфизм в том смысле, что для массива типа Cloneable нельзя вызвать данный метод. Поэтому по сути использование данного интерфейса ничем не лучше, чем предоставление классу аналогичной функциональности через метод с другим именем и без использования данного интерфейса.

3.2. Пример альтернативного решения — использование конструктора копирования, принимающего как параметр объект копируемого типа. Одно из преимуществ конструктора: возможность сменить тип представления данных (например, скопировать данные из LinkedList в ArrayList).

3.3. Но оба вышеуказанных способа полны потенциальных ошибок. Наиболее удобным и гибким способом клонирования является механизм сериализации. Он заключается в сохранении объекта в поток байтов с последующим восстановлением. Если нет особой необходимости обработки полей во время клонирования объектов, именно сериализация является наиболее предпочтительным вариантом для этих целей.

3.3.1. Пример:
Cat vaska = new Cat("Vaska","Gray",4);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream ous = new ObjectOutputStream(baos);
//сохраняем состояние кота Васьки в поток и закрываем его(поток)
ous.writeObject(vaska);
ous.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
//создаём кота для опытов и инициализируем его состояние Васькиным
Cat cloneVaska = (Cat)ois.readObject();

Widowmaker1984, блог «Дом на краю кладбища»

Широкая русская душа

Хотел написать про вчерашний концерт "Немного нервно", но в последнее время я понемногу схожу с ума от количества объектно-ориентированности в моей жизни, поэтому эту тему придется отложить до лучших времен.

Пока шел домой из Gastonberry (клуб в честь которого даже, кажется, назвали разрушенное аббатство где-то в Англии), решил сфотографировать на лавочке книгу "Искусство и деньги". Именно ее я за отсутствием лучшей (и реализующей интерфейс Signable) альтернативы в перерыве протянул музыкантам на автографы.

Ко мне тем временем подсел незнакомый мужчина и поинтересовался, являюсь ли я патриотом. Честный ответ "в какой-то степени" его несколько разочаровал, и после истории про Березовского (который, как известно, повесился оттого, что Путин не разрешил ему вернуться на Родину) внезапный собеседник решил доходчиво и с примерами просветить меня, что же такое на самом деле "широкая русская душа".
скрытый текст
Суть примерно сводилась к тому, что иностранец, когда пьет, постоянно держит в памяти, сколько у него осталось денег. А русский же — в силу той самой широты души — остановится лишь пропив все до последней копейки, что неоднократно и на самом что ни на есть личном опыте наблюдал мой собеседник.

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



Widowmaker1984, блог «Java для собеседований»

Вопрос 91 (метод finalize и сборка мусора)

"Что такое finalize? Зачем он нужен? Что Вы можете рассказать о сборщике мусора и алгоритмах его работы."

1. В некоторых объектно-ориентированных языках, в частности в C++, есть явные деструкторы, предназначенные для уничтожения объектов. Основная их задача — освобождение памяти, занятной объектами. Поскольку в языке Java реализован механизм автоматической сборки мусора, освобождать память вручную нет никакой необходимости, поэтому в языке Java деструкторы отсутствуют.

1.1. Разумеется, некоторые объекты используют кроме памяти и другие ресурсы, например файлы, или обрабатывают другие обьекты, которые в свою очередь, обращаются к системным ресурсам. В этом случае очень важно, чтобы ресурсы вовремя освобождались.В любой класс можно добавить метод finalize(). Этот метод будет вызван при первой сборке мусора следующей за моментом когда ваш объект стал недостижим.

скрытый текст2. Не стоит полагаться на finalize для чистки данных. Во-первых, нет гарантии, что он будет вызван, т.к. где-то может остаться ссылка на объект. Во-вторых, нет гарантии, в какое время будет вызван метод. Это связано с тем, что после того, как объект становится доступным для сборки и, если в нем переопределен метод finalize, то он не вызывается сразу, а помещается в очередь, которая обрабатывается специально созданным для этого потоком. Стоит отметить, что в очередь на финализацию попадают только те объекты, в которых метод finalize переопределен.

2.1. Есть вероятность, что данный метод не будет вызван совсем, т.к. программа завершит работу раньше.

2.1.1. Существует метод System.runFinalizerOnExit(true), гарантирующий, что метод finalize() будет вызван до того, как программа корректно завершит свою работу. Однако этот метод крайне ненадежен и не рекомендован к использованию. В качестве альтернативы можно применить метод Runtime.addShutdownHook(). Дополнительную информацию о нем можно найти в документации по API.

2.1.2. Есть другой способ быть уверенным, что finalize-методы были запущены для объектов, доступных для сборки: вызвать System.runFinalization() или Runtime.getRuntime().runFinalization().

2.2. Переопределение метода finalize значительно удлиняет время жизни объекта после смерти, так как он будет удален из памяти не раньше второй сборки мусора. А учитывая два первых пункта, если метод finalize у будет тяжелым иили таких объектов будет очень много, то объекты могут довольно долго висеть в фазе финализации и продолжать занимать место в памяти.

3. Интересной особенностью метода является то, что он может снова сделать объект доступным, присвоив this какой-нибудь переменной, хотя так делать не рекомендуется, т.к. при восстановлении объекта, повторно finalize вызван не будет.

3.1. Поэтому если по каким-то причинам очень надо воскресить данный объект, лучше внутри метода finalize создать его копию.

4. Одна из самых неприятных проблем возникающих при использовании метода finalize — это реордеринг. Представьте, что есть два объекта с переопределенным методом finalize, один из которых ссылается на другой. Так вот, если эти объекты стали недостижимы, то порядок вызова методов финализации произойдет в случайном порядке. Таким образом, у вас будет потенциальная опасность вызвать какой-нибудь метод на уже финализированном объекте из метода finalize другого объекта и получить ошибку.

5. Любые исключения выброшенные в теле метода будут проигнорированы.

5.1. Надо не забыть в конце метода вызвать super.finalize(). А учитывая предыдущий пункт, сделать это необходимо в блоке finally.

6. Согласно всему вышесказанному по возможности следует избегать использование метода finalize, вернее не стоит полагаться на него. Лучше освобождать ресурсы программно, а в методе finalize логировать, если этого почему-то сделано не было, чтобы вовремя найти и починить возникшую проблему. Также можно использовать его как последний шанс закрыть ресурс

6.1. Если ресурс должен быть освобожден сразу после его использования, нужно самостоятельно написать соответствующий код. Добавьте метод dispose() или close(), который нужно явно вызвать для очистки памяти. Если класс имеет такой метод, вы должны вызвать его по завершении работы с объектом этого класса. Недостатком является то, что разработчик должен помнить, что ресурс после использования нужно закрыть.
Страницы: 1 2 3 8 следующая →

Лучшее   Правила сайта   Вход   Регистрация   Восстановление пароля

Материалы сайта предназначены для лиц старше 16 лет (16+)