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

1. Обзор

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

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

2. Javac Command

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

javac[options][source-files]----

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

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

Параметры __javac__ подразделяются на три группы: стандартные, кросс-компиляция и дополнительные. В этой статье мы остановимся на стандартных и дополнительных опциях.

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

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

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

[source,java,gutter:,true]

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

public void addText(String text) {
    textList.add(text);
}
    public List getTextList() {
        return this.textList;
    }
}
Исходный код помещается в файл __com/baeldung/javac/Data.java__.

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

===  **  4. Стандартные опции **

Одним из наиболее часто используемых стандартных параметров команды __javac__ является __-d__, **  указывающий каталог назначения для сгенерированных файлов классов ** .

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

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

[source,bash,gutter:,true]

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

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

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

**  **  __- cp__ (или __-classpath__, __ – class-path__) - **  указывает, где типы

Необходимые для компиляции наши исходные файлы можно найти. Если эта опция отсутствует и переменная среды __CLASSPATH__ не установлена, вместо нее используется текущий рабочий каталог (как это было в примере выше).

**  **  __- p__ (или __ – module-path__) - **  указывает на местоположение необходимого

прикладные модули. Эта опция применима только к Java 9 и выше - пожалуйста, обратитесь к ссылке:/project-jigsaw-java-modularity[это руководство]для руководства к модульной системе Java 9.

Если мы хотим знать, что происходит во время процесса компиляции, например,

какие классы загружены, а какие скомпилированы, мы можем применить параметр __-verbose__.

Последний стандартный вариант, который мы рассмотрим, это файл аргументов. **  Вместо передачи аргументов непосредственно в инструмент __javac__, мы можем сохранить их в файлах аргументов ** . Имена этих файлов с префиксом «‘ @ __‘__ »затем используются в качестве аргументов команды.

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

Предположим, у нас есть два файла с именами __options__ и __types__ в каталоге __javac-args__ со следующим содержимым:

Файл __options__:

[source,text,gutter:,true]

-d javac-target -verbose

Файл __types__:

[source,text,gutter:,true]

com/baeldung/javac/Data.java

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

[source,bash,gutter:,true]

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

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

Предположим, что в каталоге __javac-args__ есть файл с именем __arguments__:

[source,text,gutter:,true]

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

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

[source,bash,gutter:,true]

javac @javac-args/arguments

Обратите внимание, что варианты, которые мы рассмотрели в этом разделе, являются наиболее распространенными. Полный список стандартных параметров __javac__ см. По ссылке https://docs.oracle.com/javase/9/tools/javac.htm#GUID-AEEC9F07-CB49-4E96-8BC7-BCC2C7F725C9____STANDARDOPTIONSFORJAVAC-7D3D9CC2[this.

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

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

Однако есть опция, которая очень полезна и заслуживает упоминания, __-Xlint__. Чтобы получить полное описание других дополнительных параметров __javac__, перейдите по ссылке https://docs.oracle.com/javase/9/tools/javac.htm#GUID-AEEC9F07-CB49-4E96-8BC7-BCC2C7F725C9____NONSTANDARDOPTIONSFORJAVAC-7D3DAA9D.

**  Параметр __-Xlint__ позволяет нам включать предупреждения во время компиляции ** .

Есть два способа указать эту опцию в командной строке:

**  **  __- Xlint –__ **  вызывает все рекомендуемые предупреждения

**  **  __- Xlint: ключ[, ключ]**  –__ **  включает определенные предупреждения

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

**  **  __rawtypes –__ **  предупреждает об использовании необработанных типов

**  **  __unchecked –__ **  предупреждает о непроверенных операциях

**  **  __static –__ **  предупреждает о доступе к статическому члену из

член экземпляра
**  **  __cast –__ **  предупреждает о ненужных приведениях

**  **  __serial –__ **  предупреждает о сериализуемых классах, не имеющих

__serialversionUID__
**  **  __fallthrough –__ **  предупреждает о проваливании в __switch__

заявление

Теперь создайте файл с именем __xlint-ops__ в каталоге __javac-args__ со следующим содержимым:

[source,text,gutter:,true]

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

При запуске этой команды:

[source,bash,gutter:,true]

javac @javac-args/xlint-ops

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

[source,text,gutter:,false]

com/baeldung/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/baeldung/javac/Data.java:7: warning:[unchecked]unchecked conversion List<String> textList = new ArrayList(); ^ required: List<String> found: ArrayList …​

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

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

В действительности мы обычно компилируем программу, используя IDE или инструмент сборки, а не полагаясь непосредственно на __javac__. Тем не менее, глубокое понимание этого инструмента позволит нам настроить компиляцию в сложных случаях использования.

Как всегда, исходный код этого руководства можно найти на https://github.com/eugenp/tutorials/tree/master/core-java/[over на GitHub].