Spec-Zone .ru
спецификации, руководства, описания, API
|
javac [ options ] [ sourcefiles ] [ classes ] [ @argfiles ]
Параметры могут быть в любом порядке.
options
sourcefiles
classes
@argfiles
-J
опции не позволяются в этих файлах.javac инструмент читает класс и интерфейсные определения, записанные в языке программирования Java, и компилирует их в файлы класса байт-кода. Это может также обработать аннотации в исходных файлах Java и классах.
Есть два способа передать имена файлов исходного кода к javac:
Имена файлов исходного кода должны иметь .java
суффиксы, имена файлов класса должны иметь .class
у суффиксов, и и источник и файлы класса должны быть корневые имена, которые идентифицируют класс. Например, класс вызывают MyClass
был бы записан в вызванном исходном файле MyClass.java
и скомпилированный в файл класса байт-кода вызывается MyClass.class
.
Внутренние определения классов производят дополнительные файлы класса. У этих файлов класса есть имена, комбинирующие внутренние и внешние имена классов, такой как MyClass$MyInnerClass.class
.
Следует расположить исходные файлы в дереве каталогов, которое отражает их дерево пакета. Например, если Вы сохраняете все свои исходные файлы в C:\workspace, исходном коде для com.mysoft.mypack.MyClass
должен быть в C:\workspace\com\mysoft\mypack\MyClass.java.
По умолчанию компилятор помещает каждый файл класса в тот же самый каталог как его исходный файл. Можно определить разделять целевой каталог с-d (см. Опции, ниже).
У компилятора есть ряд стандартных опций, которые поддерживаются на текущей среде разработки и будут поддерживаться в будущих выпусках. Дополнительный набор нестандартных опций является определенным для текущей виртуальной машины и реализаций компилятора и является подверженным изменениям в будущем. Нестандартные опции начинаются с-X.
Если-sourcepath опция не определяется, пользовательский путь к классу также ищется исходные файлы.
Если-processorpath опция не определяется, путь к классу также ищется процессоры аннотации.
com.mypackage.MyClass
, тогда файл класса вызывают C:\myclasses\com\mypackage\MyClass.class
. Если-d не определяется, javac помещает каждый класс файлы в тот же самый каталог как исходный файл, от которого это было сгенерировано.
Отметьте: каталог, определенный-d, автоматически не добавляется к Вашему пользовательскому пути к классу.
EUC-JP and UTF-8
. Если - кодирование не определяется, преобразователь значения по умолчанию платформы используется.ext
каталог. Переменная каталогов является разделенным от двоеточия списком каталогов. Каждый архив JAR в указанных каталогах ищется файлы класса. Все найденные архивы JAR являются автоматически частью пути к классу. Если Вы кросс-компилируете (компиляция классов против классов начальной загрузки и расширения различной реализации платформы Java), эта опция определяет каталоги, которые содержат классы расширения. См. Опции Кросс-компиляции для получения дополнительной информации.
Отметьте: ПУТЬ К КЛАССУ, - путь к классу,-bootclasspath, и-extdirs не определяет классы, используемые, чтобы выполнить javac. Игра с реализацией компилятора таким образом обычно бессмысленна и всегда опасна. Если Вы действительно должны сделать это, используйте-J опцию, чтобы пройти через опции к базовому средству запуска java.
com.mypackage.MyClass
, тогда исходный файл будет помещен в C:\mysrc\com\mypackage\MyClass.java
.Отметьте: Классы, найденные через путь к классу, могут подвергнуться автоматической перекомпиляции, если их источники также находятся. См. Поиск Типов.
По умолчанию классы компилируются против классов начальной загрузки и расширения платформы это javac, поставленный с. Но javac также поддерживает кросс-компиляцию, где классы компилируются против классов начальной загрузки и расширения различной реализации платформы Java. Важно использовать-bootclasspath и-extdirs, кросс-компилируя; см. Пример Кросс-компиляции ниже.
Значение по умолчанию для - цель зависит от значения - источник:
System.err
.SOURCE
.Позвольте предупредить имя с опцией-Xlint:name, где имя является одним из следующих имен предупреждения. Точно так же можно отключить предупреждение имени с опцией - Xlint:-имя:
String s = (String)"Hello!"
java.util.Date myDate = new java.util.Date(); int currentDay = myDate.getDay();
Метод java.util.Date.getDay
был осужден начиная с JDK 1.1.
@deprecated
Javadoc комментируют, но не имеют a @Deprecated
аннотация. Например: /** * @deprecated As of Java SE 7, replaced by {@link #newMethod()} */ public static void deprecatedMethood() { } public static void newMethod() { }
int divideByZero = 42 / 0;
if
операторы. Например: class E { void m() { if (true) ; } }
switch (x) { case 1: System.out.println("1"); // No break statement here. case 2: System.out.println("2"); }
Если бы флаг -Xlint:fallthrough использовался, компилируя этот код, то компилятор испустил бы предупреждение о "возможном, проваливаются в случай," наряду с номером строки рассматриваемого случая.
finally
пункты, которые не могут обычно завершаться. Например: public static int m() { try { throw new NullPointerException(); } catch (NullPointerException e) { System.err.println("Caught NullPointerException."); return 1; } finally { return 0; } }
Компилятор генерирует предупреждение для finally
блок в этом примере. Когда этот метод вызывают, он возвращает значение 0
, нет 1
. A finally
блок всегда выполняется когда try
блочные выходы. В этом примере, если управление передается catch
, тогда выходы метода. Однако, finally
блок должен быть выполнен, таким образом, он выполняется, даже при том, что управление было уже передано вне метода.
public class ClassWithVarargsMethod { void varargsMethod(String... s) { } }
public class ClassWithOverridingMethod extends ClassWithVarargsMethod { @Override void varargsMethod(String[] s) { } }
Компилятор генерирует предупреждение, подобное следующему:
warning: [override] varargsMethod(String[]) in ClassWithOverridingMethod overrides varargsMethod(String...) in ClassWithVarargsMethod; overriding method is missing '...'
Когда компилятор встречается с varargs методом, он преобразовывает varargs формальный параметр в массив. В методе ClassWithVarargsMethod.varargsMethod
, компилятор преобразовывает varargs формальный параметр String... s
к формальному параметру String[] s
, массив, который соответствует формальный параметр метода ClassWithOverridingMethod.varargsMethod
. Следовательно, этот пример компиляции.
@SuppressWarnings
аннотация. Например: javac -Xlint:path -classpath C:\nonexistentpath Example.java
Исходный файл AnnoProc.java
:
import java.util.*; import javax.annotation.processing.*; import javax.lang.model.*; import javax.lang.model.element.*; @SupportedAnnotationTypes("NotAnno") public class AnnoProc extends AbstractProcessor { public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv) { return true; } public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); } }
Исходный файл AnnosWithoutProcessors.java
:
@interface Anno { } @Anno class AnnosWithoutProcessors { }
Следующие команды компилируют процессор аннотации AnnoProc
, тогда выполните этот процессор аннотации против исходного файла AnnosWithoutProcessors.java
:
% javac AnnoProc.java % javac -cp . -Xlint:processing -processor AnnoProc -proc:only AnnosWithoutProcessors.java
Когда компилятор выполняет процессор аннотации против исходного файла AnnosWithoutProcessors.java
, это генерирует следующее предупреждение:
warning: [processing] No processor claimed any of these annotations: Anno
Чтобы решить этот вопрос, можно переименовать аннотацию, определенную и используемую в классе AnnosWithoutProcessors
от Anno
к NotAnno
.
rawtypes
предупреждение: void countElements(List l) { ... }
Следующее не генерирует a rawtypes
предупреждение:
void countElements(List<?> l) { ... }
List
необработанный тип. Однако, List<?>
неограниченный подстановочный знак параметризованный тип. Поскольку List
параметризованный интерфейс, следует всегда определять его параметр типа. В этом примере, List
формальный параметр определяется с неограниченным подстановочным знаком (?
) как его формальный параметр типа, что означает что countElements
метод может принять любое инстанцирование List
интерфейс.
serialVersionUID
определения на сериализуемых классах. Например: public class PersistentTime implements Serializable { private Date time; public PersistentTime() { time = Calendar.getInstance().getTime(); } public Date getTime() { return time; } }
Компилятор генерирует следующее предупреждение:
warning: [serial] serializable class PersistentTime has no definition of serialVersionUID
Если сериализуемый класс явно не объявляет названное поле serialVersionUID
, тогда время выполнения сериализации вычислит значение по умолчанию serialVersionUID
значение для того класса, основанного на различных аспектах класса, как описано в Спецификации Сериализации Объекта Java. Однако, строго рекомендуется, чтобы все сериализуемые классы явно объявили serialVersionUID
значения, потому что процесс по умолчанию вычислений serialVersionUID
долины очень чувствительны к деталям класса, которые могут измениться в зависимости от реализаций компилятора, и могут таким образом привести к неожиданному InvalidClassExceptions
во время десериализации. Поэтому, чтобы гарантировать непротиворечивое serialVersionUID
значение через различные реализации компилятора Java, сериализуемый класс должен объявить явное serialVersionUID
значение.
class XLintStatic { static void m1() { } void m2() { this.m1(); } }
Компилятор генерирует следующее предупреждение:
warning: [static] static method should be qualified by type name, XLintStatic, instead of by an expression
Чтобы решить этот вопрос, можно вызвать статический метод m1
следующим образом:
XLintStatic.m1();
Альтернативно, можно удалить static
ключевое слово от объявления метода m1
.
try
блоки, включая операторы попытки с ресурсами. Например, предупреждение сгенерировано для следующего оператора потому что ресурс ac
объявленный в try
оператор не используется: try ( AutoCloseable ac = getResource() ) { // do nothing }
List l = new ArrayList<Number>(); List<String> ls = l; // unchecked warning
Во время стирания типа, типов ArrayList<Number>
и List<String>
стать ArrayList
и List
, соответственно.
Переменная ls
имеет параметризованный тип List<String>
. Когда List
ссылаемый l
присваивается ls
, компилятор генерирует предупреждение непроверенное; компилятор неспособен определить во время компиляции, и кроме того знает, что JVM не будет в состоянии определить во время выполнения, если l
обращается к a List<String>
введите; это не делает. Следовательно, загрязнение "кучи" происходит.
Подробно, ситуация с загрязнением "кучи" происходит когда List
объект l
, чей статический тип List<Number>
, присваивается другому List
объект, ls
, у этого есть различный статический тип, List<String>
. Однако, компилятор все еще позволяет это присвоение. Это должно позволить этому присвоению сохранять назад совместимость с версиями Java SE, которые не поддерживают обобщения. Из-за стирания типа, List<Number>
и List<String>
оба становятся List
. Следовательно, компилятор позволяет присвоение объекта l
, у которого есть необработанный тип List
, к объекту ls
.
public class ArrayBuilder { public static <T> void addToList (List<T> listArg, T... elements) { for (T x : elements) { listArg.add(x); } } }
Компилятор генерирует следующее предупреждение для определения метода ArrayBuilder.addToList
:
warning: [varargs] Possible heap pollution from parameterized vararg type T
Когда компилятор встречается с varargs методом, он преобразовывает varargs формальный параметр в массив. Однако, язык программирования Java не разрешает создание массивов параметризованных типов. В методе ArrayBuilder.addToList
, компилятор преобразовывает varargs формальный параметр T... elements
к формальному параметру T[] elements
, массив. Однако, из-за стирания типа, компилятор преобразовывает varargs формальный параметр в Object[] elements
. Следовательно, есть возможность загрязнения "кучи".
Чтобы сократить или упростить javac командную строку, можно определить один или более файлов, которые непосредственно содержат параметры javac
команда (кроме -J
опции). Это позволяет Вам создать javac команды любой длины на любой операционной системе.
Файл параметра может включать javac опции и исходные имена файлов в любой комбинации. Параметры в пределах файла могут быть разделены пробелом или разделены от новой строки. Если имя файла содержит встроенные пробелы, помещало целое имя файла в двойные кавычки, и удваивает каждую наклонную черту влево ("My Files\\Stuff.java"
).
Имена файлов в пределах файла параметра относительно текущего каталога, не расположения файла параметра. Подстановочные знаки (*) не позволяются в этих списках (такой что касается определения *.java
). Использование символа '@', чтобы рекурсивно интерпретировать файлы не поддерживается. -J
опции не поддерживаются, потому что их передают к средству запуска, которое не поддерживает файлы параметра.
Выполняясь javac, передайте в пути и имени каждого файла параметра с '@' ведущий символ. Когда javac встречается с параметром, начинающимся с символьного `@', он разворачивает содержание того файла в список параметров.
Вы могли использовать единственный файл параметра, названный"argfile
"чтобы содержать все javac параметры:
C:> javac @argfile
Этот файл параметра мог содержать содержание обоих файлов, показанных в следующем примере.
Можно создать два файла параметра - один для javac опций и другого для исходных имен файлов: (Заметьте, что у следующих списков нет никаких символов продолжения строки.)
Создайте файл, названный"options
"содержа:
-d classes -g -sourcepath C:\java\pubs\ws\1.3\src\share\classes
Создайте файл, названный"classes
"содержа:
MyClass1.java MyClass2.java MyClass3.java
Вы тогда выполнили бы javac с:
C:> javac @options @classes
У файлов параметра могут быть пути, но любые имена файлов в файлах относительно текущего рабочего каталога (нет path1
или path2
):
C:> javac @path1\options @path2\classes
javac оказывает прямую поддержку для обработки аннотации, заменяя потребность в отдельном инструменте обработки аннотации, склонном.
API для процессоров аннотации определяется в javax.annotation.processing
и javax.lang.model
пакеты и подпакеты.
Если обработка аннотации не отключается с-proc:none опцией, поиски компилятора никаких процессоров аннотации, которые доступны. Путь поиска может быть определен с-processorpath опцией; если это не дается, пользовательский путь к классу используется. Процессоры располагаются посредством названных конфигурационных файлов поставщика услуг META-INF/services/javax.annotation.processing.Processor
на пути поиска. Такие файлы должны содержать имена любых процессоров аннотации, которые будут использоваться, перечисленные один на строку. Альтернативно, процессоры могут быть определены явно, используя - опция процессора.
После сканирования исходных файлов и классов на командной строке, чтобы определить, какие аннотации присутствуют, компилятор запрашивает процессоры, чтобы определить, какие аннотации они обрабатывают. Когда соответствие будет найдено, процессор будет вызван. Процессор может "требовать" аннотаций, которые он обрабатывает, когда никакая дальнейшая попытка не предпринимается, чтобы найти любые процессоры для тех аннотаций. Как только все аннотации требовались, компилятор не ищет дополнительные процессоры.
Если какие-либо процессоры генерируют какие-либо новые исходные файлы, то другой раунд обработки аннотации произойдет: любые недавно сгенерированные исходные файлы будут отсканированы, и аннотации, обработанные как прежде. Любые процессоры, вызванные на предыдущие раунды, будут также вызваны на все последующие раунды. Это продолжается, пока никакие новые исходные файлы не сгенерированы.
После того, как раунд происходит, где никакие новые исходные файлы не сгенерированы, процессоры аннотации будут вызваны в один прошлый раз, чтобы дать им шанс завершить любую работу, которую они, возможно, должны сделать. Наконец, если-proc:only опция не используется, компилятор скомпилирует оригинал и все сгенерированные исходные файлы.
Чтобы скомпилировать ряд исходных файлов, компилятор, возможно, должен неявно загрузить дополнительные исходные файлы. (См. Поиск Типов). Такие файлы в настоящий момент не подвергаются обработке аннотации. По умолчанию компилятор даст предупреждение, если обработка аннотации произошла, и любые неявно загруженные исходные файлы компилируются. См. - неявная опция для способов подавить предупреждение.
Компилируя исходный файл, компилятор часто нуждается в информации о типе, определение которого не появлялось в исходных файлах, данных на командной строке. Компилятор нуждается в информации о типе для каждого класса или интерфейса, используемого, расширенного, или реализованный в исходном файле. Это включает классы и интерфейсы, не явно упомянутые в исходном файле, но которые предоставляют информацию посредством наследования.
Например, когда Вы разделяете java.applet на подклассы. Апплет, Вы также используете классы предка Апплета: java.awt. Панель, java.awt. Контейнер, java.awt. Компонент, и java.lang. Объект.
Когда компилятор нуждается в информации о типе, он ищет исходный файл или файл класса, который определяет тип. Компилятор ищет файлы класса сначала в классах начальной загрузки и расширения, затем в пользовательском пути к классу (который по умолчанию является текущим каталогом). Пользовательский путь к классу определяется, устанавливая переменную окружения ПУТИ К КЛАССУ или при использовании - параметр командной строки пути к классу. (Для получения дополнительной информации см. Установку Пути к классу).
Если Вы устанавливаете-sourcepath опцию, компилятор ищет обозначенный путь исходные файлы; иначе компилятор ищет пользовательский путь к классу и файлы класса и исходные файлы.
Можно определить различные классы начальной загрузки или расширения с-bootclasspath и-extdirs опциями; см. Опции Кросс-компиляции ниже.
Успешный поиск типа может произвести файл класса, исходный файл, или обоих. Если оба находятся, можно использовать-Xprefer опцию, чтобы сообщить компилятору, чтобы использовать. Если более новый дается, компилятор будет использовать более новые из этих двух файлов. Если источник будет дан, то он будет использовать исходный файл. Значение по умолчанию более ново.
Если поиск типа найдет исходный файл для необходимого типа, или отдельно, или в результате установки для-Xprefer, то компилятор считает исходный файл, чтобы получить информацию, в которой это нуждается. Кроме того, это будет значением по умолчанию компилировать исходный файл также. Можно использовать - неявная опция, чтобы определить поведение. Если ни один не будет дан, то никакие файлы класса не будут сгенерированы для исходного файла. Если класс будет дан, то файлы класса будут сгенерированы для исходного файла.
Компилятор, возможно, не обнаруживает потребность в некоторой информации о типе, пока обработка аннотации не полна. Если информация о типе находится в исходном файле и нет - неявная опция дается, компилятор даст предупреждение, что файл компилируется, не будучи подвергающимся обработке аннотации. Чтобы отключить предупреждение, любой определяет файл на командной строке (так, чтобы это подверглось обработке аннотации), или используйте - неявная опция, чтобы определить, должны ли файлы класса быть сгенерированы для таких исходных файлов.
javac поддерживает новый API Компилятора Java, определенный классами и интерфейсами в javax.tools
пакет.
Чтобы выполнить компиляцию, используя параметры, поскольку Вы дали бы на командной строке, можно использовать следующее:
JavaCompiler javac = ToolProvider.getSystemJavaCompiler(); int rc = javac.run(null, null, null, args);
Это запишет любую диагностику в поток стандартного вывода, и возвратит код выхода, который javac дал бы когда вызвано из командной строки.
Можно использовать другие методы на javax.tools.JavaCompiler
взаимодействуйте через интерфейс, чтобы обработать диагностику, управление, где файлы читаются из и пишутся и так далее.
Отметьте: Этот API сохраняется для назад совместимости только; весь новый код должен использовать API Компилятора Java, описанный выше.
com.sun.tools.javac.Main
класс обеспечивает два статических метода, чтобы вызвать компилятор из программы:
public static int compile(String[] args); public static int compile(String[] args, PrintWriter out);
args
параметр представляет любой из параметров командной строки, которые обычно передавали бы к javac программе и обрисовываются в общих чертах в вышеупомянутом разделе Резюме.
out
параметр указывает, где диагностический вывод компилятора направляется.
Возвращаемое значение эквивалентно значению выхода от javac.
Отметьте, что все другие классы и методы, найденные в пакете, имя которого запускается с com.sun.tools.javac
(неофициально известный как подпакеты com.sun.tools.javac
) являются строго внутренними и подлежат изменению в любое время.
Один исходный файл, Hello.java
, определяет класс, названный поздравлениями. Привет. greetings
каталог является каталогом пакета и для исходного файла и для файла класса и от текущего каталога. Это позволяет нам использовать пользовательский путь к классу по умолчанию. Это также делает ненужным определить разделять целевой каталог с-d.
C:> dir greetings C:> dir greetings Hello.java C:> cat greetings\Hello.java package greetings; public class Hello { public static void main(String[] args) { for (int i=0; i < args.length; i++) { System.out.println("Hello " + args[i]); } } } C:> javac greetings\Hello.java C:> dir greetings Hello.class Hello.java C:> java greetings.Hello World Universe Everyone Hello World Hello Universe Hello Everyone
Этот пример компилирует все исходные файлы в пакете greetings
.
C:> dir greetings\ C:> dir greetings Aloha.java GutenTag.java Hello.java Hi.java C:> javac greetings\*.java C:> dir greetings Aloha.class GutenTag.class Hello.class Hi.class Aloha.java GutenTag.java Hello.java Hi.java
Изменив один из исходных файлов в предыдущем примере, мы перекомпилировали это:
C:> cd \examples C:> javac greetings\Hi.java
С тех пор greetings.Hi
обращается к другим классам в greetings
пакет, компилятор должен найти эти другие классы. Пример выше работ, потому что наш пользовательский путь к классу по умолчанию, оказывается, каталог, содержащий каталог пакета. Но предположите, что мы хотим перекомпилировать этот файл и не беспокойство, о котором каталоге мы находимся в? Затем мы должны добавить \examples
к пользовательскому пути к классу. Мы можем сделать это установкой CLASSPATH, но здесь мы будем использовать - опция пути к классу.
C:>javac -classpath \examples \examples\greetings\Hi.java
Если мы изменяемся greetings.Hi
снова, чтобы использовать утилиту баннера, та утилита также должна быть доступной через пользовательский путь к классу.
C:>javac -classpath \examples;\lib\Banners.jar \ \examples\greetings\Hi.java
Выполнить класс в greetings
, мы нуждаемся в доступе оба к greetings
и к классам это использует.
C:>java -classpath \examples;\lib\Banners.jar greetings.Hi
Часто имеет смысл сохранять исходные файлы и файлы класса в отдельных каталогах, особенно на крупных проектах. Мы используем-d, чтобы указать на отдельное место назначения файла класса. Так как исходные файлы не находятся в пользовательском пути к классу, мы используем-sourcepath, чтобы помочь компилятору найти их.
C:> dir classes\ lib\ src\ C:> dir src farewells\ C:> dir src\farewells Base.java GoodBye.java C:> dir lib Banners.jar C:> dir classes C:> javac -sourcepath src -classpath classes;lib\Banners.jar \ src\farewells\GoodBye.java -d classes C:> dir classes farewells\ C:> dir classes\farewells Base.class GoodBye.class
Отметьте: компилятор скомпилирован src\farewells\Base.java
, даже при том, что мы не определяли это на командной строке. Чтобы проследить автоматические компиляции, используйте - многословная опция.
Здесь мы используем javac, чтобы скомпилировать код, который будет работать на 1.7 VM.
% javac -target 1.7 -bootclasspath jdk1.7.0\lib\rt.jar \ -extdirs "" OldCode.java
- предназначаются для 1.7 опций, гарантирует, что сгенерированные файлы класса будут совместимыми с 1.7 VMs. По умолчанию javac компилирует для JDK 6.
javac JDK Платформы Java был бы также компиляцией по умолчанию против ее собственных классов начальной загрузки, таким образом, мы должны сказать javac компилировать против JDK 1.7 класса начальной загрузки вместо этого. Мы делаем это с-bootclasspath и-extdirs. Будучи не в состоянии сделать это могло бы позволить компиляцию против API Платформы Java, который не будет присутствовать на 1.7 VM и перестал бы работать во время выполнения.