Spec-Zone .ru
спецификации, руководства, описания, API
|
javac [ options ] [ sourcefiles ] [ classes ] [ @argfiles ]
Параметры могут быть в любом порядке.
options
sourcefiles
classes
@argfiles
-J
опции не позволяются в этих файлах.javac инструмент читает class и определения интерфейса, записанные в языке программирования Java, и компилирует их в байт-код файлы class. Это может также обработать аннотации в исходных файлах Java и классах.
Есть два способа передать имена файлов исходного кода к javac:
Имена файлов исходного кода должны иметь .java
суффиксы, имена файлов class должны иметь .class
у суффиксов, и и источник и файлы class должны быть корневые имена, которые идентифицируют class. Например, class вызывают MyClass
был бы записан в вызванном исходном файле MyClass.java
и скомпилированный в байт-код файл class вызывают MyClass.class
.
Внутренние определения class производят дополнительные файлы class. У этих файлов class есть имена, комбинирующие внутренние и внешние имена class, такой как MyClass$MyInnerClass.class
.
Следует расположить исходные файлы в дереве каталогов, которое отражает их дерево пакета. Например, если Вы сохраняете все свои исходные файлы в C:\workspace, исходном коде для com.mysoft.mypack.MyClass
должен быть в C:\workspace\com\mysoft\mypack\MyClass.java.
По умолчанию компилятор помещает каждый файл class в тот же самый каталог как его исходный файл. Можно определить разделять целевой каталог с-d (см. Опции, ниже).
У компилятора есть ряд стандартных опций, которые поддерживаются на текущей среде разработки и будут поддерживаться в будущих выпусках. Дополнительный набор нестандартных опций является определенным для текущей виртуальной машины и реализаций компилятора и является подверженным изменениям в будущем. Нестандартные опции начинаются с-X.
Если-sourcepath опция не определяется, пользователь, путь class также ищется исходные файлы.
Если-processorpath опция не определяется, путь class также ищется процессоры аннотации.
com.mypackage.MyClass
, тогда файл class вызывают C:\myclasses\com\mypackage\MyClass.class
. Если-d не определяется, javac помещает каждый class файлы в тот же самый каталог как исходный файл, от которого это было сгенерировано.
Отметьте: каталог, определенный-d, автоматически не добавляется к Вашему пользователю путь class.
EUC-JP and UTF-8
. Если - кодирование не определяется, преобразователь значения по умолчанию платформы используется.ext
каталог. Переменная каталогов является разделенным от двоеточия списком каталогов. Каждый архив JAR в указанных каталогах ищется файлы class. Все найденные архивы JAR являются автоматически частью пути class. Если Вы кросс-компилируете (компиляция классов против классов начальной загрузки и расширения различной реализации платформы Java), эта опция определяет каталоги, которые содержат классы расширения. См. Опции Кросс-компиляции для получения дополнительной информации.
Отметьте: ПУТЬ К КЛАССУ, - путь к классу,-bootclasspath, и-extdirs не определяет классы, используемые, чтобы выполнить javac. Игра с реализацией компилятора таким образом обычно бессмысленна и всегда опасна. Если Вы действительно должны сделать это, используйте-J опцию, чтобы пройти через опции к базовому средству запуска java.
com.mypackage.MyClass
, тогда исходный файл будет помещен в C:\mysrc\com\mypackage\MyClass.java
.Отметьте: Классы, найденные через путь class, могут подвергнуться автоматической перекомпиляции, если их источники также находятся. См. Поиск Типов.
По умолчанию классы компилируются против классов начальной загрузки и расширения платформы это 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
:
C:\>javac AnnoProc.java C:\>javac -cp . -Xlint:processing -processor AnnoProc -proc:only AnnosWithoutProcessors.java
Когда компилятор выполняет процессор аннотации против исходного файла AnnosWithoutProcessors.java
, это генерирует следующее предупреждение:
warning: [processing] No processor claimed any of these annotations: Anno
Чтобы решить этот вопрос, можно переименовать аннотацию, определенную и используемую в class 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
Если сериализуемый class явно не объявляет названное поле serialVersionUID
, тогда время выполнения сериализации вычислит значение по умолчанию serialVersionUID
значение, для что class, основанный на различных аспектах class, как описано в Спецификации Сериализации Объекта Java. Однако, строго рекомендуется, чтобы все сериализуемые классы явно объявили serialVersionUID
значения, потому что процесс значения по умолчанию вычислений serialVersionUID
долины очень чувствительны к деталям class, которые могут измениться в зависимости от реализаций компилятора, и могут таким образом привести к неожиданному InvalidClassExceptions
во время десериализации. Поэтому, чтобы гарантировать непротиворечивое serialVersionUID
значение через различные реализации компилятора Java, сериализуемый class должен объявить явное 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 опцией; если это не дается, пользователь, путь class используется. Процессоры располагаются посредством названных конфигурационных файлов поставщика услуг META-INF/services/javax.annotation.processing.Processor
на пути поиска. Такие файлы должны содержать имена любых процессоров аннотации, которые будут использоваться, перечисленные один на строку. Альтернативно, процессоры могут быть определены явно, используя - опция процессора.
После сканирования исходных файлов и классов на командной строке, чтобы определить, какие аннотации присутствуют, компилятор запрашивает процессоры, чтобы определить, какие аннотации они обрабатывают. Когда соответствие будет найдено, процессор будет вызван. Процессор может "требовать" аннотаций, которые он обрабатывает, когда никакая дальнейшая попытка не предпринимается, чтобы найти любые процессоры для тех аннотаций. Как только все аннотации требовались, компилятор не ищет дополнительные процессоры.
Если какие-либо процессоры генерируют какие-либо новые исходные файлы, то другой раунд обработки аннотации произойдет: любые недавно сгенерированные исходные файлы будут отсканированы, и аннотации, обработанные как прежде. Любые процессоры, вызванные на предыдущие раунды, будут также вызваны на все последующие раунды. Это продолжается, пока никакие новые исходные файлы не сгенерированы.
После того, как раунд происходит, где никакие новые исходные файлы не сгенерированы, процессоры аннотации будут вызваны в один прошлый раз, чтобы дать им шанс завершить любую работу, которую они, возможно, должны сделать. Наконец, если-proc:only опция не используется, компилятор скомпилирует оригинал и все сгенерированные исходные файлы.
Чтобы скомпилировать ряд исходных файлов, компилятор, возможно, должен неявно загрузить дополнительные исходные файлы. (См. Поиск Типов). Такие файлы в настоящий момент не подвергаются обработке аннотации. По умолчанию компилятор даст предупреждение, если обработка аннотации произошла, и любые неявно загруженные исходные файлы компилируются. См. - неявная опция для способов подавить предупреждение.
Компилируя исходный файл, компилятор часто нуждается в информации о типе, определение которого не появлялось в исходных файлах, данных на командной строке. Компилятор нуждается в информации о типе для каждого class или интерфейса, используемого, расширенного, или реализованный в исходном файле. Это включает классы и интерфейсы, не явно упомянутые в исходном файле, но которые предоставляют информацию посредством наследования.
Например, когда Вы разделяете java.applet на подклассы. Апплет, Вы также используете классы предка Апплета: java.awt. Панель, java.awt. Контейнер, java.awt. Компонент, и java.lang. Объект.
Когда компилятор нуждается в информации о типе, он ищет исходный файл или файл class, который определяет тип. Компилятор ищет файлы class сначала в классах начальной загрузки и расширения, затем в пользователе путь class (который по умолчанию является текущим каталогом). Пользователь путь class определяется, устанавливая переменную окружения ПУТИ К КЛАССУ или при использовании - параметр командной строки пути к классу. (Для получения дополнительной информации см. Установку Пути к классу).
Если Вы устанавливаете-sourcepath опцию, компилятор ищет обозначенный путь исходные файлы; иначе компилятор ищет пользователя путь class и файлы class и исходные файлы.
Можно определить различные классы начальной загрузки или расширения с-bootclasspath и-extdirs опциями; см. Опции Кросс-компиляции ниже.
Успешный поиск типа может произвести файл class, исходный файл, или обоих. Если оба находятся, можно использовать-Xprefer опцию, чтобы сообщить компилятору, чтобы использовать. Если более новый дается, компилятор будет использовать более новые из этих двух файлов. Если источник будет дан, то он будет использовать исходный файл. Значение по умолчанию более ново.
Если поиск типа найдет исходный файл для необходимого типа, или отдельно, или в результате установки для-Xprefer, то компилятор считает исходный файл, чтобы получить информацию, в которой это нуждается. Кроме того, это будет значением по умолчанию компилировать исходный файл также. Можно использовать - неявная опция, чтобы определить поведение. Если ни один не будет дан, то никакие файлы class не будут сгенерированы для исходного файла. Если class будет дан, то файлы class будут сгенерированы для исходного файла.
Компилятор, возможно, не обнаруживает потребность в некоторой информации о типе, пока обработка аннотации не полна. Если информация о типе находится в исходном файле и нет - неявная опция дается, компилятор даст предупреждение, что файл компилируется, не будучи подвергающимся обработке аннотации. Чтобы отключить предупреждение, любой определяет файл на командной строке (так, чтобы это подверглось обработке аннотации), или используйте - неявная опция, чтобы определить, должны ли файлы class быть сгенерированы для таких исходных файлов.
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
class обеспечивает два статических метода, чтобы вызвать компилятор из программы:
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
) являются строго внутренними и подлежат изменению в любое время.
Следующий исходный файл, C:\greetings\Hello.java
, определяет class, названный поздравлениями. Привет:
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]); } } }
greetings
каталог является каталогом пакета и для исходного файла и для файла class и от текущего каталога. Это позволяет нам использовать пользователя значения по умолчанию путь class. Это также делает ненужным определить разделять целевой каталог с-d.
C:\>javac greetings\Hello.java C:\>dir greetings /B Hello.class Hello.java C:\>java greetings.Hello World Universe Everyone Hello World Hello Universe Hello Everyone
Этот пример компилирует все исходные файлы в пакете greetings
.
C:\>dir /B greetings C:\>dir greetings /B Aloha.java GutenTag.java Hello.java Hi.java C:\>javac greetings\*.java C:\>dir greetings /B Aloha.class Aloha.java GutenTag.class GutenTag.java Hello.class Hello.java Hi.class Hi.java
Изменив один из исходных файлов в предыдущем примере, мы перекомпилировали это:
C:\>cd \examples C:\>javac greetings\Hi.java
С тех пор greetings.Hi
обращается к другим классам в greetings
пакет, компилятор должен найти эти другие классы. Пример выше работ, потому что наш пользователь значения по умолчанию путь class, оказывается, каталог, содержащий каталог пакета. Но предположите, что мы хотим перекомпилировать этот файл и не беспокойство, о котором каталоге мы находимся в? Затем мы должны добавить \examples
пользователю путь class. Мы можем сделать это установкой CLASSPATH, но здесь мы будем использовать - опция пути к классу.
C:\>javac -classpath \examples \examples\greetings\Hi.java
Если мы изменяемся greetings.Hi
снова, чтобы использовать утилиту баннера, та утилита также должна быть доступной через пользователя путь class.
C:\>javac -classpath \examples;\lib\Banners.jar ^ \examples\greetings\Hi.java
Выполнить class в greetings
, мы нуждаемся в доступе оба к greetings
и к классам это использует.
C:\>java -classpath \examples;\lib\Banners.jar greetings.Hi
Часто имеет смысл сохранять исходные файлы и файлы class в отдельных каталогах, особенно на крупных проектах. Мы используем-d, чтобы указать на отдельное место назначения файла class. Так как исходные файлы не находятся в пользователе путь class, мы используем-sourcepath, чтобы помочь компилятору найти их.
C:\>dir /B 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.6 VM.
C\:>javac -source 1.6 -target 1.6 -bootclasspath C:\jdk1.6.0\lib\rt.jar ^ -extdirs "" OldCode.java
-source 1.6
опция определяет что версия 1.6 (или 6) языка программирования Java использоваться, чтобы скомпилировать OldCode.java
. Опция - предназначается для 1.6 опций, гарантирует, что сгенерированные файлы class будут совместимыми с 1.6 VMs. Отметьте, что в большинстве случаев, значение - целевая опция является значением - исходная опция; в этом примере можно опустить - целевая опция.
Следует определить-bootclasspath опцию, чтобы определить корректную версию классов начальной загрузки ( rt.jar
библиотека). В противном случае компилятор генерирует предупреждение:
C:\>javac -source 1.6 OldCode.java warning: [options] bootstrap class path not set in conjunction with -source 1.6
Если Вы не определите корректную версию классов начальной загрузки, то компилятор будет использовать старые правила языка (в этом примере, это будет использовать версию 1.6 языка программирования Java), объединенный с новыми классами начальной загрузки, которые могут привести к файлам class, которые не работают над более старой платформой (в этом случае, Java SE 6), потому что ссылка на несуществующие методы может быть включена.