У меня 15-летний опыт работы с C ++, но я новичок в Java.
Самая большая проблема, с которой вы, вероятно, столкнетесь, состоит в том, что многие вещи, которые рассматриваются как важные в C ++, такие какsizeof () объект, целые числа без знака и деструкторы, нелегко сделать в Java и не имеют такого же значения и имеют другие решения / обходные пути.
Я пытаюсь понять, какОтсутствие заголовочных файлов обрабатывается Java.У меня есть несколько вопросов, связанных с этой проблемой.
В Java есть интерфейсы, которые по своей концепции аналогичны заголовочным файлам в том смысле, что они содержат только объявления (и константы) без определений.Классы часто соединяются с интерфейсом для этого класса, иногда один к одному.
Использует ли компилятор загрузчик классов для загрузки Z (для повторения - во время компиляции)?
Когда загрузчик классов загружает класс, он вызывает статический блок инициализации, который может делать что угодно.Все, что нужно компилятору - это извлечь метаданные из класса, а не байт-код, и это то, что он делает.
именно MAVEN отвечает за загрузку стороннего JAR-файла при компиляциивремя, а не JVM компилятора?
Maven должен загрузить файл в локальную файловую систему, расположение по умолчанию: ~/.m2/repository
как JRE узнает, где скачатьZ.class (без помощи Maven)?
Он должен либо использовать Maven;Некоторые контейнеры OSGi могут загружать и выгружать разные версии динамически, например, вы можете изменить версию библиотеки в работающей системе или обновить SNAPSHOT из сборки maven.
Или у вас есть отдельное приложение;Используя плагин Maven, такой как appassembly, вы можете создать пакетный скрипт / shell-скрипт и каталог с копией всех необходимых вам библиотек.
Или веб-архив war
, который содержит метаинформацию и множество jar-файлов внутри.(Это просто баночка с банками;)
Или разработчик должен отправить Z.class вместе с A.class с приложением
Для автономного приложенияда.
Теперь связанный вопрос, просто для подтверждения: я предполагаю, что после компиляции A.class содержит только символические ссылки на Z.class
Технически, это толькосодержит строки с Z
, а не .class
.Вы можете изменить много Z без компиляции A снова, и он все равно будет работать.Например, вы можете скомпилировать одну версию Z и заменить ее другой версией позже, и приложение все еще может работать.Вы даже можете заменить его во время работы приложения.;)
байт-коды Z.class не являются частью A.class;
Компилятор почти не оптимизируется.Единственное существенное ИМХО, это то, что он встроен в константы времени компиляции.Это означает, что если вы измените константу в Z после компиляции A, она не может измениться в A. (Если вы сделаете константу, неизвестную во время компиляции, она не будет встроена в нее)
Никакой байт-код не встроен,нативный код из байтового кода вставляется во время выполнения в зависимости от того, как на самом деле работает программа.Например, у вас есть виртуальные методы с N реализациями.Компилятор C ++ не знает, какие из них встроить в esp, поскольку они могут быть недоступны во время компиляции.Однако JVM может видеть, какие из них используются чаще всего (она собирает статистику во время работы программы) и может использовать две наиболее часто используемые реализации.(Пища для размышления относительно того, что происходит, когда вы удаляете / обновляете один из этих классов во время выполнения;)
Пожалуйста, исправьте меня, если я ошибаюсь.(В C ++ статическое связывание будет копировать байты из Z.class в A.class, тогда как динамическое связывание не будет.)
Java имеет только динамическое связывание, но это не предотвращает встраивание кода ввремя выполнения, которое так же эффективно, как и использование макроса.
Другой связанный с этим вопрос, касающийся процесса компиляции: как только необходимые файлы, описывающие Z, находятся в CLASSPATH во время компиляции, требуется ли компилятору байт-коды из Z.class для компиляции A.java (и будет собирать Z.class(если необходимо, из Z.java) или Z.java достаточно для компилятора?
Компилятор будет компилировать все файлы .java
по мере необходимости.Вам нужно только указать .java
, но он должен скомпилироваться (т.е. его зависимости должны быть доступны). Однако, если вы используете файл .class
, не все его зависимости должны быть доступны для компиляции A.
Мое общее замешательство можно резюмировать следующим образом.Кажется, что полный [байтовый] код для Z должен присутствовать ДВАЖДЫ - один раз во время компиляции и второй раз во время выполнения -
Технически класс содержит байт-код и метаданные, такие каксигнатуры методов, поля и константы.Ни один байт-код не используется во время компиляции, только метаинформация.Байт-код во время компиляции не должен совпадать с тем, который используется во время выполнения.(Используемые сигнатуры / поля делают) Просто проще иметь по одной копии каждого класса, но вы можете использовать урезанную версию во время компиляции, если вам нужно для какой-то цели.
и этоэто должно быть верно для ВСЕХ классов, на которые ссылается программа Java.Другими словами, каждый класс должен быть загружен / представлен ДВАЖДЫ.Ни один класс не может быть представлен во время компиляции как просто файл заголовка (как это может быть в C ++).
Его нужно загрузить только один раз, так как он находится в хранилище или где-то еще на вас.диск.Интерфейсы, такие как заголовки, могут быть всем, что вам нужно во время компиляции, и это может быть отдельная библиотека, но обычно это не так, поскольку в большинстве случаев проще иметь один архив (OSGi - единственный известный мне пример того, где он находитсястоит разделить их)