Время компиляции vs Время выполнения Зависимость – Java

В чем разница между временем компиляции и временем выполнения в Java? Это связано с курсом classа, но как они отличаются?

  • Зависимость времени компиляции : вам нужна зависимость в вашем CLASSPATH для компиляции вашего артефакта. Они создаются, потому что у вас есть какая-то «ссылка» на зависимость, жестко закодированную в вашем коде, например, вызов new для какого-либо classа, расширение или реализацию чего-либо (прямо или косвенно) или вызов метода с использованием прямого reference.method() обозначение.

  • Зависимость времени выполнения : вам нужна зависимость в вашем CLASSPATH для запуска вашего артефакта. Они создаются, потому что вы выполняете код, который обращается к зависимостям (либо жестко, либо через reflection или что-то еще).

Хотя зависимость времени компиляции обычно подразумевает зависимость времени выполнения, вы можете иметь только зависимость от времени компиляции. Это основано на том факте, что Java связывает только зависимости classа от первого доступа к этому classу, поэтому, если вы никогда не получаете доступ к определенному classу во время выполнения, потому что путь кода никогда не пересекается, Java игнорирует как class, так и его зависимости.

Пример этого

В C.java (генерирует C.class):

 package dependencies; public class C { } 

В A.java (генерирует A.class):

 package dependencies; public class A { public static class B { public String toString() { C c = new C(); return c.toString(); } } public static void main(String[] args) { if (args.length > 0) { B b = new B(); System.out.println(b.toString()); } } } 

В этом случае A имеет зависимость от времени компиляции от C до B , но будет иметь только зависимость времени выполнения от C, если вы передадите некоторые параметры при выполнении java dependencies.A Поскольку JVM будет только пытаться решить B ‘ s на C когда он получает выполнение B b = new B() . Эта функция позволяет вам во время выполнения предоставлять только зависимости classов, которые вы используете в своих кодах, и игнорировать зависимости остальных classов в артефакте.

Простым примером является просмотр api, как api сервлета. Чтобы скомпилировать servlets, вам нужен servlet-api.jar, но во время выполнения контейнер сервлета предоставляет реализацию api сервлета, поэтому вам не нужно добавлять servlet-api.jar в свой путь к classу среды выполнения.

Компилятору нужен правильный путь к classам для компиляции вызовов в библиотеку (скомпилировать временные зависимости)

JVM нуждается в правильном пути к classам, чтобы загрузить classы в вызываемой библиотеке (зависимости от времени выполнения).

Они могут быть разными по-разному:

1) если ваш class C1 вызывает библиотечный class L1, а L1 вызывает библиотечный class L2, тогда C1 имеет зависимость времени выполнения от L1 и L2, но только зависимость времени компиляции от L1.

2) если ваш class C1 динамически создает интерфейс I1, используя Class.forName () или какой-либо другой механизм, а class реализации для интерфейса I1 – это class L1, тогда C1 имеет зависимость от времени выполнения от I1 и L1, но только зависимость времени компиляции на I1.

Другие «косвенные» зависимости, которые одинаковы для времени компиляции и времени выполнения:

3) ваш class C1 расширяет библиотечный class L1, а L1 реализует интерфейс I1 и расширяет библиотечный class L2: C1 имеет зависимость времени компиляции от L1, L2 и I1.

4) ваш class C1 имеет метод foo(I1 i1) и bar(L1 l1) методов bar(L1 l1) где I1 является интерфейсом, а L1 – это class, который принимает параметр, который является интерфейсом I1: C1 имеет зависимость времени компиляции от I1 и L1.

В принципе, чтобы сделать что-нибудь интересное, вашему classу необходимо взаимодействовать с другими classами и интерфейсами в пути к classам. График classа / интерфейса, образованный этим набором интерфейсов библиотеки, дает цепочку зависимостей времени компиляции. Реализации библиотеки дают цепочку зависимостей во время выполнения. Обратите внимание, что цепочка зависимостей во время выполнения зависит от времени выполнения или с ошибкой: если реализация L1 иногда зависит от создания экземпляра объекта classа L2, и этот class получает экземпляр только в одном конкретном сценарии, тогда нет никакой зависимости, кроме этот сценарий.

Java фактически не связывает ничего во время компиляции. Он проверяет только синтаксис, используя соответствующие classы, которые он находит в CLASSPATH. Только во время выполнения все объединяется и выполняется на основе CLASSPATH в то время.

Зависимости Compiletime – это только зависимости (другие classы), которые вы используете непосредственно в classе, который вы компилируете. Зависимости времени выполнения include как прямые, так и косвенные зависимости classа, который вы используете. Таким образом, зависимости времени выполнения зависят от зависимостей зависимостей и любых зависимостей отражения, таких как Class#forName() которые у вас есть в String , но используются в Class#forName() .

Для Java зависимость времени компиляции зависит от вашего исходного кода. Например, если class A вызывает метод из classа B, то A зависит от B во время компиляции, так как A должен знать о B (тип B), который должен быть скомпилирован. Трюк здесь должен быть следующим: Скомпилированный код еще не является полным и исполняемым кодом. Он включает сменные адреса (символы, метаданные) для источников, которые еще не скомпилированы или не существуют во внешних баночках. При связывании эти адреса должны быть заменены фактическими адресами в памяти. Чтобы сделать это правильно, необходимо создать правильные символы / адреса. И это можно сделать с типом classа (B). Я считаю, что это основная зависимость во время компиляции.

Зависимость времени выполнения больше связана с фактическим streamом контроля. Он включает фактические адреса памяти. Это зависимость, которая у вас есть при запуске вашей программы. Вам нужны данные classа B здесь, как реализации, а не только информация типа. Если class не существует, вы получите RuntimeException и JVM выйдет.

Обе зависимости, как правило, так и не должны, течет в одном направлении. Это вопрос дизайна OO.

В C ++ компиляция немного отличается (не точно в срок), но у нее тоже есть компоновщик. Таким образом, процесс можно считать похожим на Java, я думаю.

  • Как получить x и y windows программы на Java?
  • Добавление файлов в java classpath во время выполнения
  • Создать JPA EntityManager без файла конфигурации persistence.xml
  • На лету, компиляция Java-кода в памяти для Java 5 и Java 6
  • Динамическое изменение уровня журнала log4j
  • Выполнение внешней программы в java
  • выполнить код c # во время выполнения из файла кода
  • Как установить среду java в Windows 8?
  • Получение имени параметра метода
  • читать вывод из java exec
  • Удалить контейнер верхнего уровня во время выполнения
  • Interesting Posts
    Давайте будем гением компьютера.