Comments 23
В четвёртой задаче я рассуждал, что ничего не мешает создать свой класс class java.lang.Integer implements Iterable
и загрузить кастомным класслоадером. Ну или в bootstrap classpath подсунуть. Нет?
java.lang.*
классы могут загружаться только в bootstrap класслоадере, с просто кастомным не выйдет. Через bootclasspath вероятно можно, но мой пример все-равно злее: он дергает (x instanceof Iterable<?>)
и выводит false
.
Задача 1 — почему область видимости obj заканчивается? Потому что дальше не используется?
Область видимости ограничена фигурными скобками, поэтому заканчивается только в конце. А вот область жизни заканчивается после передачи в конструктор, потому что дальше нет использований.
Пару слов об "области жизни", я думал, что она возможно будет и больше "области видимости".
Если пытаться говорить корректно, то область видимости (переменной) — термин исходного кода, а область жизни (значения) — термин внутреннего представления компилятора. Сразу после разбора исходного кода область видимости переменной строго больше области жизни соответствующих значений, однако после оптимизаций (например, протяжки присваиваний) область жизни может существенно увеличиться и превзойти оригинальную область видимости. Или же уменьшиться как в задаче.
К сожалению, держать переменные "живыми" очень накладно. Компилятор делает все возможное, чтобы минимизировать количество таких переменных в каждый момент времени, чтобы по-больше влезло на регистры процессора, чтобы по-меньше читать память.
Но в целом, если бы вариант D был единственным, мир наш был бы светлее. :)
Если вам специалньо нужно подержать переменную, для этого есть специальный API-метод Reference.reachabilityFence(). Нужен он в реальной жизни исключительно редко, а из-за такой оптимизации вы получаете существенный прирост в производительности вашей программы нахаляву.
habrahabr.ru/post/350638/#comment_10710890
habrahabr.ru/post/350638/#comment_10710912
habrahabr.ru/post/350638/#comment_10712452
или даже не ответить, а натолкнуть на размышления…
1. я чётко понимаю, что подобный функционал появился не на ровном месте а в погоне за производительностью, и что да, действительно держать переменные живыми. Это очевидно
2. Ну слава «кофе», что выставление границ появилось, правда только в 9, а до этого обманывать оптимизаторы надо было различными фейковыми действиями, скрестив пальцы, что «так» удастся наколоть оптимизатор
3. Никакого возмущения, чистая прагматика:
— назовите 3 книги по JAVA где написано, что область действия переменной НЕРАВНА области видимости, давно не заглядывал в книги, надо проверить, но уверен что если 3 наберется, то уже неплохо. А в целом продолжаем учить язык и писать на нём не правильно
— один раз написано — работает? мы сломали принцип? да не, фигня, главное чтоб побыстрее работало =) а принципы и концепции мы молотком по пальцам
— вектор развития языка и его основополагающих принципов (область видимости) как обход и перепрыгивание багов, которые возникли из-за попыток оптимизации?! Это ли наш настоящий джедайский путь
— я обеими клешнями за развитие и ускорение языка, но впереди телеги всё таки пусть катиться концепция. А может я просто ретроград, что мне при таком развитии спокойнее
Я также четко понимаю (так на всякий случай :) что уж ничего не поменять и ИМХО это моё частное мнение, которое ничего не поменяет (всем надо больше золота) и нам всем с этим жить.
Поэтому спасибо ребятам из Excelsior и других не менее крутых контор за то что фиксируете такие тонкости для публики. Интересно про то знать и читать.
И тут же пожелание всем мегагуру, которые пилят для нас VM — ломайте концепции языка пореже, нам всем с этим жить же =)
назовите 3 книги по JAVA где написано, что область действия переменной НЕРАВНА области видимости
JLS считается за такую книжку? Думаю, ее можно засчитать за три. Вот там в параграфе 12.6.1 (спасибо @shipilev за наводку) сказано:
Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. For example, a Java compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.
Лично мне не совсем понятно, почему Вы считаете, что выживание переменных в области видимости, — это какой-то «принцип» или «концепция», которую бессовестно сломали при реализации. Так сделано в C++, например, но нас то это ни к чему не обязывает.
А в чем проблема-то?
(Как это может отразиться на коде?)
Хардкорные Java/JVM задачки