Много есть в Java, друг Горацио, что и не снилось привыкшим к циклам for/else

Автоp статьи начал свое изучение мира Java со стандартных вопросов. Почему язык Java разработан специально с расчетом на генерацию байт-кода? Насколько сложными являются виртуальные машины, интерпретирующие байт-код для конкретного компьютера? И, наконец, можно ли говорить о том, что переносимость легка? Благодаря волшебным возможностям Usenet вы узнаете, что думают по этому поводу знающие люди.

Я отношусь к тем представителям рода человеческого, которым всегда хочется узнать как можно больше. Если у вас есть дети, вам знакома эта ситуация: я никогда не стану настолько взрослым, чтобы перестать задавать этот сакраментальный вопрос «почему?».

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

Теперь занялся изысканиями, связанными с изучением Java, - этот проект интересует меня вот уже шесть недель.

Я сделал все, что положено новичку, постигающему азы программирования. Я устанавливал различные IDE, покупал книги и приобрел JDK. Побывал на узле Sun, просматривал JavaWorld и постигал тайны AWT.

О, я даже выполнил несколько упражнений!

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

Первый класс

Особенно мне не давали покоя два вопроса. Признаться, приобретя определенный уровень знаний (в конце концов, я не пишу масштабные, многопоточные, оптимизированные распределенные приложения), я мог бы на этом успокоиться. Но не сделал этого. Во-первых, чтобы поддержать свой интерес к предмету, а во-вторых, чтобы лучше понимать статьи и информацию на узлах, которые теперь имею обыкновение старательно штудировать. В силу вышесказанного я отослал в конференции comp.lang.java.advocacy и comp.lang.java.help три своих вопроса.

  1. Почему Java и компилируется и интерпретируется?
  2. Почему виртуальные машины (JVM) отличаются друг от друга?
  3. Трудно ли написать (JVM)?

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

Зато в конференциях я получил с десяток превосходных откликов, каждый из которых был достаточно информативен.

И что более важно - каждый ответ содержал, дополнял и расширял предыдущий.

К примеру, Билл Уилкинсон, работающий в компании SuperCede, в которой создавался один из компиляторов Java, прислал очень полный ответ на первый вопрос. Хенк Дэвидсон из Corel подробно разъяснил проблему, поднятую во втором вопросе. А Брайан Кламик и Расс Литл в ярких красках изложили историю разработки и конкуренции вокруг Java и предпринимаемые в связи с этим действия Sun.

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

Билл Уилкинсон объясняет

Итак, вопрос был таков: почему для языка Java нужен и компилятор и интерпретатор?

Билл пишет:

«...Исходный текст (понятный человеку) компилируется в псевдодвоичный код (называемый байт-кодом). Именно псевдокод загружается и интерпретируется на клиентской машине. Почему байтовый, а не исходный текст? Байт-код значительно меньше, чем исходный текст. Обычно он даже меньше истинно двоичного (машинного) кода. Поэтому он и загружается быстрее. Почему байт-код надо интерпретировать? А затем, что теоретически вы должны создавать только интерпретатор (часть JVM) - один раз для каждой из машинных архитектур. И даже в этой ситуации интерпретатор сам по себе достаточно просто переносится с одной архитектуры на другую.

Однако ситуация осложняется тем, что большинство современных виртуальных машин (например, те, что встроены в IE и Navigator) содержат в себе компилятор байт-кода! Иногда называемые JIT-компиляторами (just-in-time - «моментальный», «сиюминутный»), они преобразуют байт-код в машинный для конкретного компьютера, на котором они работают, и таким образом генерируют код, исполняемый на порядок быстрее, чем это возможно при непосредственной интерпретации байт-кода.

Но и это еще не все. Сейчас на рынке появились продукты, которые будут компилировать исходные тексты на Java (помните, понятный человеку текст) или байт-код (то, что обычно пересылается по сети) в привычные исполняемые модули. То есть они действуют во многом аналогично традиционным компиляторам для таких языков, как Си, Pascal, C++ и тому подобных. Эти исполняемые модули должны теоретически работать даже быстрее, чем код, созданный JIT-компиляторами, и могут стать предпочтительным решением для игр и серверов (где на счету каждый машинный цикл)».

Разный смысл на разных машинах, или спасибо, Хенк

Оставшиеся два вопроса - почему так отличаются друг от друга виртуальные машины и трудно ли их создавать - заставляют задуматься о положении в отрасли, а также оценить технические реалии.

Стоить отметить, что с недавних пор уместность подобных обсуждений стала очевидной, поскольку Microsoft умышленно добавляет новые ключевые слова к своей версии Java, пытаясь еще теснее привязать язык к Windows.

Хенк Дэвидсон из Corel пишет:

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

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

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

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

Наконец, виртуальная машина Java не есть нечто монолитное. Даже для каждой версии Java существует несколько ревизий. Компания, которая переносит реализацию Sun на другую платформу, вынуждена каждый раз после выпуска новой версии модернизировать свою реализацию с учетом исправленных ошибок и новых возможностей, добавленных Sun. Компания, у которой достаточно средств, скорее всего, могла бы адекватно отражать все изменения, но фирма, которая наподобие Apple или Netscape занята борьбой за свое «место под солнцем», стремясь удержать позиции на рынке, может не сохранить темп. Так что на практике существует много различных виртуальных машин, и неудивительно, что некоторым разработчикам приходится бороться с их несовместимостью».

Вопрос приоритета

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

Но даже самая мирная дискуссия, по всей видимости, не обходится без обсуждения трех вопросов: действительно ли Java представляет собой нечто новое, насколько он необходим и в самом ли деле является кроссплатформенным?

Несколько респондентов подчеркнули, что заслуги Java не столь уж бесспорны, а Sun нельзя назвать изобретателем концепции виртуальной машины.

Другие, похоже, рассматривают Java главным образом как политический маневр. Брайан Страустрап, создатель C++, в одном из последних интервью заметил, что «впервые в истории столь крупная корпорация выбрала язык программирования как способ выживания на рынке».

Мобильность Java: выдумка или реальность

Является ли Java действительно кроссплатформенным - с помощью дополнений Microsoft или без оных? Получить четкий ответ на этот вопрос так и не удалось. Фактически именно это заставляет меня усомниться в столь широко рекламируемых достоинствах Java.

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

Не это ли мы привыкли называть «хорошей переносимостью»?

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

Поэтому наступит время, когда программы, написанные на Java 1.0, не будут работать на большинстве виртуальных машин. По-видимому, Sun весьма импонирует лозунг 'Написано однажды, работает везде' (вероятно, лишь в течение ограниченного срока)».

Все, о чем говорилось выше, в большей степени обусловлено личными мотивами, чем важностью вопроса о всемогуществе Java. Почему? Потому, что я хочу изучать объектно-ориентированное программирование.

А Java, с его четкой и логичной структурой, богатством печатных и интерактивных справочных материалов и сообществом разработчиков, озадаченных развитием новой парадигмы, в действительности лишь усложняет эту задачу.