Перейти к основному содержимому

Компиляция файлов Java *.class с помощью javac

· 5 мин. чтения

Задача: Сумма двух чисел

Напишите функцию twoSum. Которая получает массив целых чисел nums и целую сумму target, а возвращает индексы двух чисел, сумма которых равна target. Любой набор входных данных имеет ровно одно решение, и вы не можете использовать один и тот же элемент дважды. Ответ можно возвращать в любом порядке...

ANDROMEDA

1. Обзор

В этом руководстве будет представлен инструмент javac и описано, как использовать его для компиляции исходных файлов Java в файлы классов.

Мы начнем с краткого описания команды javac , а затем более подробно рассмотрим этот инструмент, рассмотрев его различные параметры.

2. Команда javac

Мы можем указать параметры и исходные файлы при выполнении инструмента javac :

javac [options] [source-files]

Где [options] обозначает параметры, управляющие работой инструмента, а [source-files] указывает один или несколько исходных файлов, которые необходимо скомпилировать.

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

Опции javac делятся на три группы: стандартные, кросс-компиляция и дополнительные. В этой статье мы сосредоточимся на стандартных и дополнительных опциях.

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

3. Определение типа

Давайте начнем с представления класса, который мы собираемся использовать для демонстрации параметров javac :

public class Data {
List<String> textList = new ArrayList();

public void addText(String text) {
textList.add(text);
}

public List getTextList() {
return this.textList;
}
}

Исходный код размещен в файле com/foreach/javac/Data.java .

Обратите внимание, что в этой статье мы используем разделители файлов *nix; на машинах Windows мы должны использовать обратную косую черту (' \' ) вместо прямой косой черты (' /' ).

4. Стандартные варианты

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

Давайте выполним следующую команду в каталоге, содержащем структуру, представленную в предыдущем разделе:

javac -d javac-target com/foreach/javac/Data.java

Компилятор javac создаст файл класса javac-target/com/foreach/javac/Data.class . Обратите внимание, что в некоторых системах javac не создает автоматически целевой каталог, которым в данном случае является javac-target . Поэтому нам может потребоваться сделать это вручную.

Вот еще несколько часто используемых опций:

  • -cp (или -classpath , –class -path ) — указывает, где можно найти типы, необходимые для компиляции наших исходных файлов. Если этот параметр отсутствует и переменная среды CLASSPATH не задана, вместо нее используется текущий рабочий каталог (как в примере выше).
  • -p (или --module-path ) – указывает расположение необходимых модулей приложения. Эта опция применима только к Java 9 и более поздним версиям — пожалуйста, обратитесь к этому руководству за руководством по модульной системе Java 9.

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

Последним стандартным вариантом, который мы рассмотрим, является файл аргументов. Вместо того, чтобы передавать аргументы непосредственно инструменту javac , мы можем хранить их в файлах аргументов . Имена этих файлов с префиксом '@ ' затем используются в качестве аргументов команды.

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

Предположим, у нас есть два файла с именами options и types в каталоге javac-args со следующим содержимым:

Файл опций :

-d javac-target
-verbose

Файл типов :

com/foreach/javac/Data.java

Мы можем скомпилировать тип данных , как и раньше, с подробными сообщениями, напечатанными на консоли, выполнив эту команду:

javac @javac-args/options @javac-args/types

Вместо того, чтобы хранить аргументы в отдельных файлах, мы также можем хранить их все в одном файле .

Предположим, что в каталоге javac-args есть файл с именем arguments : ``

-d javac-target -verbose
com/foreach/javac/Data.java

Давайте передадим этот файл в javac , чтобы получить тот же результат, что и с двумя отдельными файлами ранее :

javac @javac-args/arguments

Обратите внимание, что варианты, которые мы рассмотрели в этом разделе, являются только наиболее распространенными. Полный список стандартных параметров javac см. в этом справочнике .

5. Дополнительные параметры

Дополнительные параметры javac — это нестандартные параметры, которые относятся к текущей реализации компилятора и могут быть изменены в будущем. Поэтому мы не будем подробно рассматривать эти варианты.

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

Параметр -Xlint позволяет нам включить предупреждения во время компиляции . Есть два способа указать эту опцию в командной строке:

  • -Xlint — вызывает все рекомендуемые предупреждения
  • -Xlint:key[,key]* — включает определенные предупреждения

Вот некоторые из самых удобных ключей -Xlint :

  • rawtypes — предупреждает об использовании необработанных типов
  • unchecked – предупреждает о непроверенных операциях
  • static — предупреждает о доступе к статическому члену из экземпляра члена
  • cast — предупреждает о ненужных бросках
  • serial — предупреждает о сериализуемых классах, не имеющих serialversionUID
  • fallthrough — предупреждает о провале в операторе switch

Теперь создайте файл с именем xlint-ops в каталоге javac-args со следующим содержимым:

-d javac-target
-Xlint:rawtypes,unchecked
com/foreach/javac/Data.java

При выполнении этой команды:

javac @javac-args/xlint-ops

мы должны увидеть необработанные типы и непроверенные предупреждения:

com/foreach/javac/Data.java:7: warning: [rawtypes] found raw type: ArrayList
List<String> textList = new ArrayList();
^
missing type arguments for generic class ArrayList<E>
where E is a type-variable:
E extends Object declared in class ArrayList
com/foreach/javac/Data.java:7: warning: [unchecked] unchecked conversion
List<String> textList = new ArrayList();
^
required: List<String>
found: ArrayList
...

6. Заключение

В этом руководстве рассматривается инструмент javac , показывая, как использовать параметры для управления типичным процессом компиляции.

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

Как всегда, исходный код этого руководства можно найти на GitHub .