Сегодня обнаружил интересную багу. Не сразу понял в чем проблема, пока не запустил дебаггер :)
Есть такой класс А
Есть вот такой наследник класса A:
Есть еще один наследник класса А:
Внимание, вопрос:
Какой результат выведется на экран, если запустить метод A.main?
Правильный ответ (для JDK 6):
null
foo2
Интересный задротский вопрос для собеседования получился, включу в собеседование на сеньорную позицию в Java :)
А знаешь почему так случается? При компиляции final полей с изначально установленным значением происходит вставка значения во все места в коде, где используется поле. Если ты его не сможешь поменять, то почему бы не прооптимизировать. После компиляции происходит так
ReplyDeletepublic class AChild2 extends A {
public AChild2() {
}
protected String getFoo() {
return "foo1";
}
private final String foo = "foo1";
}
Тогда как во втором классе, инициализация перенесется в конструктор, который выполнится сразу после отработки конструктора суперкласса (который запрашивает поле, но пока еще со значением null).
public class AChild1 extends A {
public AChild1() {
foo = "foo1";
}
protected String getFoo() {
return foo;
}
private String foo;
}
Нахимичили. Сколько еще таких подводных камней.
Только вот я с tdd перестал париться по поводу чего-то типа этого примера. Мне обычно тесты говорят, что я что-то упустил. Тут же включается любознательность и открываю новое. Потом уже знаю, и могу поумничать на собеседовании. Вопрос в том, Сережа, что бы ты ответил на такое на собеседовании?
Спасибо, Саш за разьяснение :)
DeleteДавно я не ходил на собеседования. Хотя я иногда задаю подобные вопросы на синьорских интервью. Но я оцениваю не правильный ответ, а ход мысли человека и его возможность включить мозг в экстренной ситуации. Понятно, что мало кто знает детали оптимизации кода, но иногда имея базовые понятия можно дойти до правильного ответа самому.
Так что я бы, скорее всего, попытался максимально включить логику и излагал бы ход своих мыслей интервьюеру. Дошел бы до правильного ответа или нет - не знаю, но если бы я не прошел интервью из-за того, что не дал правильного ответа в этом вопросе, то не огорчился бы. С задротами, которые требуют доскональных ответов на вопросы типа "чем отличается WeakReference от SoftReference" или "в какой версии Servlet спецификации появились фильтры" иногда бывает неинтересно работать :).
Серега, и очень здорово что так. Тогда правильный ответ - jad :) Я им пользуюсь регулярно, когда какая-то митстика появляется. А когда вижу что по факту с кодом произошло после компиляции, то ищу описание почему это так в документации.
DeleteНо перед jad я бы написал пачку тестов на интеерсный кейс, который вызывает у меня сомнения, причем кейс акуратно выкристализовал бы из легаси кода, с которым работал в такой же примерчик как у тебя.
Ну и в блог естественно! Если причерчик очень интересный.
Часто, такие интересные кейсы как грибы, очень прячутся под листвой, а потому только что-то идет не так как я себе запланировал с кодом - верный признак, надо копнуть - где-то я чего-то не знаю.
Только вот когда я так начинаю рассуждать на собеседовании, то на меня как-то странно косятся. В глазах читается "это надо знать!". Им почему-то пофиг, что подобные алгоритмы работают везде, и не важно j2ee это или php, или разворачивания moodle на бесплатном хостинге или что-то еще новое.