Java Language
Команда Java - «java» и «javaw»
Поиск…
Синтаксис
java [ <opt> ... ] <class-name> [ <argument> ... ]
java [ <opt> ... ] -jar <jar-file-pathname> [ <argument> ... ]
замечания
Команда java
используется для запуска приложения Java из командной строки. Он доступен как часть Java SE JRE или JDK.
В системах Windows есть два варианта команды java
:
- Вариант
java
запускает приложение в новом окне консоли. - Вариант
javaw
запускает приложение без создания нового окна консоли.
В других системах (например, Linux, Mac OSX, UNIX) предоставляется только команда java
, и она не запускает новое консольное окно.
Символ <opt>
в синтаксисе обозначает параметр в командной строке java
. Темы «Параметры Java» и «Параметры выбора кучи и размера стека» охватывают наиболее часто используемые параметры. Другие описаны в теме JVM Flags .
Запуск исполняемого файла JAR
Исполняемые файлы JAR - это самый простой способ собрать Java-код в один файл, который можно выполнить. * (Редакционное примечание: создание JAR-файлов должно охватываться отдельной темой.) *
Предполагая, что у вас есть исполняемый JAR-файл с именем пути <jar-path>
, вы должны иметь возможность запускать его следующим образом:
java -jar <jar-path>
Если команде требуются аргументы командной строки, добавьте их после <jar-path>
. Например:
java -jar <jar-path> arg1 arg2 arg3
Если вам нужно предоставить дополнительные параметры JVM в командной строке java
, они должны пройти до опции -jar
. Обратите внимание , что -cp
/ -classpath
опция будет игнорироваться , если вы используете -jar
. Путь к классам приложения определяется манифестом JAR-файла.
Запуск приложений Java через «основной» класс
Когда приложение не было упаковано в качестве исполняемого JAR, вам необходимо указать имя класса точки входа в командной строке java
.
Запуск класса HelloWorld
Пример «HelloWorld» описан в разделе «Создание новой программы Java» . Он состоит из одного класса HelloWorld
который удовлетворяет требованиям для точки входа.
Предполагая, что (скомпилированный) файл HelloWorld.class находится в текущем каталоге, его можно запустить следующим образом:
java HelloWorld
Следует отметить следующие важные моменты:
- Мы должны указать имя класса: не путь к файлу «.class» или «.java».
- Если класс объявлен в пакете (как и большинство классов Java), то имя класса, которое мы поставляем команде
java
должно быть полным именем класса. Например, еслиSomeClass
объявлен в пакетеcom.example
, то полное имя класса будетcom.example.SomeClass
.
Указание пути к классам
Если мы не используем синтаксис команды java -jar
, команда java
ищет класс для загрузки путем поиска в пути к классам; см. « Класс» . Вышеприведенная команда опирается на путь по умолчанию, который является (или включает) текущий каталог. Мы можем быть более откровенными в этом вопросе, указав путь к классам, который будет использоваться с помощью опции -cp
.
java -cp . HelloWorld
Это говорит о том, чтобы сделать текущий каталог (который является тем, «означает») единственную запись в пути к классам.
-cp
- это опция, которая обрабатывается командой java
. Все параметры, предназначенные для команды java
должны быть перед именем класса. Все, что после класса будет рассматриваться как аргумент командной строки для приложения Java, и будет передано в приложение в String[]
, которое передается main
методу.
(Если опция no -cp
предоставлена, java
будет использовать путь к классам, который задается переменной среды CLASSPATH
. Если эта переменная не установлена или пуста, java
использует «.» Как путь по умолчанию по умолчанию.)
Классы точек входа
Класс точки входа Java имеет main
метод со следующими сигнатурами и модификаторами:
public static void main(String[] args)
Sidenote: из-за того, как работают массивы, он также может быть
(String args[])
Когда java
команда запускает виртуальную машину, она загружает указанные классы начальной точки и пытается найти main
. В случае успеха аргументы из командной строки преобразуются в объекты Java String
и собираются в массив. Если main
вызывается так, массив не будет null
и не будет содержать null
элементы.
Действительный метод класса входной точки должен выполнять следующие действия:
- Называть
main
(с учетом регистра) - Быть
public
иstatic
-
void
тип возвратаvoid
- Имейте один аргумент с массивом
String[]
. Аргумент должен присутствовать и допускается не более одного аргумента. - Будьте универсальными: параметры типа не допускаются.
- Имейте не общий, верхний уровень (не вложенный или внутренний) класс
Традиционно объявлять класс public
но это не является строго необходимым. Начиная с Java 5, тип аргумента main
метода может быть переменным String
вместо строкового массива. main
может опционально генерировать исключения, а его параметр можно назвать чем угодно, но обычно это args
.
Входные точки JavaFX
Начиная с Java 8, команда java
также может непосредственно запускать приложение JavaFX. JavaFX документируется в теге JavaFX , но точка входа JavaFX должна выполнять следующие действия:
- Расширить
javafx.application.Application
- Будьте
public
а неabstract
- Не быть родовым или вложенным
- Имейте явный или неявный
public
no-args
Устранение неполадок команды «java»
В этом примере рассматриваются общие ошибки с использованием команды «java».
"Команда не найдена"
Если вы получите сообщение об ошибке, например:
java: command not found
при попытке запустить java
команду это означает, что на пути поиска команд вашей оболочки нет java
команды. Причиной может быть:
- у вас нет Java JRE или JDK вообще,
- вы не обновили
PATH
средыPATH
(правильно) в файле инициализации оболочки или - вы не «получили» соответствующий файл инициализации в текущей оболочке.
Обратитесь к разделу «Установка Java» для шагов, которые необходимо предпринять.
«Не удалось найти или загрузить основной класс»
Это сообщение об ошибке выводится командой java
если не удалось найти / загрузить класс точки входа, который вы указали. В общих чертах, есть три широкие причины, которые могут произойти:
- Вы указали класс точки входа, который не существует.
- Класс существует, но вы указали его неправильно.
- Класс существует, и вы указали его правильно, но Java не может найти его, потому что путь к классам неверен.
Вот процедура диагностики и решения проблемы:
Узнайте полное имя класса точки входа.
- Если у вас есть исходный код для класса, то полное имя состоит из имени пакета и простого имени класса. Экземпляр класса «Основной» объявляется в пакете «com.example.myapp», тогда его полное имя «com.example.myapp.Main».
- Если у вас есть скомпилированный файл класса, вы можете найти имя класса, запустив
javap
. - Если файл класса находится в каталоге, вы можете вывести полное имя класса из имен каталогов.
- Если файл класса находится в JAR или ZIP-файле, вы можете сделать полное имя класса из пути к файлу в JAR или ZIP-файле.
Посмотрите сообщение об ошибке из команды
java
. Сообщение должно заканчиваться полным именем класса, которое пытается использоватьjava
.- Убедитесь, что он точно соответствует полному классу для класса начальной точки.
- Он не должен заканчиваться словами «.java» или «.class».
- Он не должен содержать косой черты или любой другой символ, который не является законным в Java-идентификаторе 1 .
- Корпус имени должен точно соответствовать полному названию класса.
Если вы используете правильное имя класса, убедитесь, что класс действительно находится в пути к классам:
- Разработайте путь, к которому сопоставляется имя класса; см. Сопоставление имен классов с именами путей
- Выясните, что такое classpath; см. этот пример: Различные способы указания пути к классам
- Посмотрите на каждый из JAR и ZIP-файлов в classpath, чтобы узнать, содержат ли они класс с требуемым именем пути.
- Посмотрите на каждую директорию, чтобы узнать, разрешает ли путь к файлу в каталоге.
Если проверка пути к классам вручную не найдена, вы можете добавить параметры -Xdiag
и -XshowSettings
. В первом перечислены все загружаемые классы, а в последнем - параметры, которые включают эффективный путь к классу JVM.
Наконец, есть некоторые неясные причины для этой проблемы:
- Исполняемый JAR-файл с атрибутом
Main-Class
который указывает класс, который не существует. - Исполняемый JAR-файл с неправильным атрибутом
Class-Path
. - Если вы испортили 2 опций перед именем класса, команда
java
может попытаться интерпретировать один из них как имя класса. - Если кто-то проигнорировал правила стиля Java и использовал идентификаторы пакетов или классов, которые отличаются только буквенным случаем, и вы работаете на платформе, которая обрабатывает регистр букв в именах файлов как несущественные.
- Проблемы с гомоглифами в именах классов в коде или в командной строке.
«Основной метод не найден в классе <имя>"
Эта проблема возникает, когда команда java
может находить и загружать назначенный вами класс, но затем не может найти метод точки входа.
Существует три возможных объяснения:
- Если вы пытаетесь запустить исполняемый JAR-файл, в манифесте JAR есть неправильный атрибут «Main-Class», который указывает класс, который не является допустимым классом точки входа.
- Вы сказали команде
java
класс, который не является классом точки входа. - Класс точки входа неверен; см. классы точек входа для получения дополнительной информации.
Другие источники
- Что означает «Не удалось найти или загрузить основной класс»?
- http://docs.oracle.com/javase/tutorial/getStarted/problems/index.html
1 - Начиная с Java 8 и более поздней версии, команда java
поможет отобразить разделитель имен файлов («/» или «») на период («.»). Однако это поведение не описано на страницах руководства.
2 - Действительно непонятным случаем является то, что вы копируете и вставляете команду из отформатированного документа, где текстовый редактор использовал «длинный дефис» вместо обычного дефиса.
Запуск приложения Java с зависимостями библиотеки
Это продолжение примеров «основного класса» и «исполняемого JAR» .
Типичные Java-приложения состоят из кода, специфичного для приложения, и другого многократного кода библиотеки, который вы реализовали или который был реализован третьими лицами. Последние обычно называются библиотечными зависимостями и обычно упаковываются в виде файлов JAR.
Java - динамически связанный язык. Когда вы запускаете приложение Java с зависимостями библиотеки, JVM должен знать, где находятся зависимости, чтобы он мог загружать классы по мере необходимости. В широком смысле, есть два способа справиться с этим:
Приложение и его зависимости можно переупаковать в один JAR-файл, содержащий все необходимые классы и ресурсы.
JVM может быть рассказано, где найти зависимые файлы JAR через путь к среде выполнения.
Для исполняемого JAR-файла путь класса выполнения задается атрибутом манифеста класса-класса. (Редакционное примечание: это должно быть описано в отдельной теме в команде jar
.) В противном случае путь к классам выполнения должен быть предоставлен с использованием параметра -cp
или с помощью переменной среды CLASSPATH
.
Например, предположим, что у нас есть приложение Java в файле «myApp.jar», чей класс точки входа com.example.MyApp
. Предположим также, что приложение зависит от библиотечных JAR-файлов «lib / library1.jar» и «lib / library2.jar». Мы могли бы запустить приложение, используя команду java
как показано в командной строке:
$ # Alternative 1 (preferred)
$ java -cp myApp.jar:lib/library1.jar:lib/library2.jar com.example.MyApp
$ # Alternative 2
$ export CLASSPATH=myApp.jar:lib/library1.jar:lib/library2.jar
$ java com.example.MyApp
(В Windows, вы должны использовать ;
вместо того , чтобы :
как разделитель пути к классам, и вы должны установить (локальный) CLASSPATH
переменную используя set
, а не export
.)
В то время как разработчику Java было бы удобно с этим, оно не «удобно». Поэтому обычной практикой является написать простой сценарий оболочки (или пакетный файл Windows), чтобы скрыть детали, о которых пользователю не нужно знать. Например, если вы поместили следующий сценарий оболочки в файл под названием «myApp», сделали его исполняемым и поместили его в каталог по пути поиска команд:
#!/bin/bash
# The 'myApp' wrapper script
export DIR=/usr/libexec/myApp
export CLASSPATH=$DIR/myApp.jar:$DIR/lib/library1.jar:$DIR/lib/library2.jar
java com.example.MyApp
то вы можете запустить его следующим образом:
$ myApp arg1 arg2 ...
Любые аргументы в командной строке будут переданы Java-приложению через расширение "$@"
. (Вы можете сделать что-то подобное с пакетным файлом Windows, хотя синтаксис отличается.)
Пробелы и другие специальные символы в аргументах
Прежде всего, проблема обработки пространств в аргументах на самом деле НЕ является проблемой Java. Скорее, это проблема, которая должна выполняться командной оболочкой, которую вы используете при запуске Java-программы.
В качестве примера предположим, что мы имеем следующую простую программу, которая печатает размер файла:
import java.io.File;
public class PrintFileSizes {
public static void main(String[] args) {
for (String name: args) {
File file = new File(name);
System.out.println("Size of '" + file + "' is " + file.size());
}
}
}
Предположим теперь, что мы хотим напечатать размер файла, у которого в нем есть пробелы; например /home/steve/Test File.txt
. Если мы запустим команду следующим образом:
$ java PrintFileSizes /home/steve/Test File.txt
оболочка не будет знать, что /home/steve/Test File.txt
на самом деле является одним из путей. Вместо этого он будет передавать два различных аргумента Java-приложению, которые будут пытаться найти их соответствующие размеры файлов и сбой, потому что файлы с этими путями (вероятно) не существуют.
Решения, использующие оболочку POSIX
Оболочки POSIX включают в себя sh
а также производные, такие как bash
и ksh
. Если вы используете одну из этих оболочек, вы можете решить проблему, указав аргумент.
$ java PrintFileSizes "/home/steve/Test File.txt"
Двойная кавычка вокруг имени пути сообщает оболочке, что она должна быть передана как один аргумент. Кавычки будут удалены, когда это произойдет. Есть несколько других способов сделать это:
$ java PrintFileSizes '/home/steve/Test File.txt'
Одиночные (прямые) кавычки рассматриваются как двойные кавычки, за исключением того, что они также подавляют различные расширения в аргументе.
$ java PrintFileSizes /home/steve/Test\ File.txt
Обратная косая черта пропускает следующее пространство и не позволяет интерпретировать ее как разделитель аргументов.
Для более полной документации, включая описание того, как обращаться с другими специальными символами в аргументах, обратитесь к теме цитирования в документации Bash .
Решение для Windows
Основная проблема для Windows заключается в том, что на уровне ОС аргументы передаются дочернему процессу как одна строка ( источник ). Это означает, что конечная ответственность за синтаксический анализ (или повторный анализ) командной строки лежит на любой программе или ее библиотеках времени исполнения. Существует много несогласованности.
В случае Java, чтобы сократить длинную историю:
Вы можете поместить двойные кавычки вокруг аргумента в команду
java
, и это позволит вам передавать аргументы с пробелами в них.По-видимому, сама команда
java
анализирует командную строку, и она становится более или менее правильнойОднако, когда вы пытаетесь объединить это с использованием замены
SET
и переменной в пакетном файле, становится очень сложно определить, удаляются ли двойные кавычки.Оболочка
cmd.exe
видимому, имеет другие механизмы экранирования; например, удвоение двойных кавычек и использование^
экранов.
Подробнее см. В документации к пакетному файлу .
Параметры Java
Команда java
поддерживает широкий диапазон опций:
Все параметры начинаются с одного символа дефиса или минус-знака (
-
): соглашение об использовании GNU / Linux для использования--
для «длинных» вариантов не поддерживается.Параметры должны появляться перед признанием
<classname>
или-jar <jarfile>
. Любые аргументы после них будут рассматриваться как аргументы, которые будут переданы в приложение Java, которое выполняется.Параметры, которые не начинаются с
-X
или-XX
являются стандартными. Вы можете полагаться на все реализации Java 1 для поддержки любой стандартной опции.Параметры, начинающиеся с
-X
являются нестандартными параметрами и могут быть удалены из одной версии Java в другую.Опции, начинающиеся с
-XX
являются расширенными опциями и могут также быть сняты.
Настройка свойств системы с помощью -D
Параметр -D<property>=<value>
используется для установки свойства в объекте Properties
системы. Этот параметр можно повторить, чтобы установить разные свойства.
Варианты памяти, стека и мусора
Основные параметры управления размерами кучи и стека описаны в разделе «Размеры кучи, пермгена и стека» . (Редакционное примечание: опции сборщика мусора должны быть описаны в той же теме.)
Включение и отключение утверждений
Параметры -ea
и -da
соответственно включают и отключают проверку assert
Java:
- По умолчанию проверка всех утверждений отключена.
- Параметр
-ea
позволяет проверять все утверждения -
-ea:<packagename>...
позволяет проверять утверждения в пакете и всех подпакетах . -
-ea:<classname>...
позволяет проверять утверждения в классе. - Параметр
-da
отключает проверку всех утверждений -
-da:<packagename>...
отключает проверку утверждений в пакете и всех подпакетах . -
-da:<classname>...
отключает проверку утверждений в классе. - Параметр
-esa
позволяет проверять все системные классы. - Параметр
-dsa
отключает проверку всех системных классов.
Параметры можно комбинировать. Например.
$ # Enable all assertion checking in non-system classes
$ java -ea -dsa MyApp
$ # Enable assertions for all classes in a package except for one.
$ java -ea:com.wombat.fruitbat... -da:com.wombat.fruitbat.Brickbat MyApp
Обратите внимание, что включение проверки достоверности может повлиять на поведение Java-программирования.
- Это может сделать приложение более медленным в целом.
- Это может привести к тому, что определенные методы потребуют больше времени для запуска, что может изменить время потоков в многопоточном приложении.
- Это может привести к неожиданным случаям - перед отношениями, которые могут привести к исчезновению аномалий памяти.
- Неправильно выполненный
assert
может иметь нежелательные побочные эффекты.
Выбор типа виртуальной машины
Параметры -client
и -server
позволяют выбирать между двумя различными формами виртуальной машины HotSpot:
- Форма «клиент» настраивается для пользовательских приложений и предлагает более быстрый запуск.
- Форма «сервер» настроена для приложений с длительным сроком службы. В процессе JVM «разогревать» требуется больше времени для сбора статистики, что позволяет компилятору JIT лучше выполнять работу по оптимизации собственного кода.
По умолчанию JVM будет работать в 64-битном режиме, если это возможно, в зависимости от возможностей платформы. Параметры -d32
и -d64
позволяют вам выбрать режим явно.
1 - Проверьте официальное руководство для команды java
. Иногда стандартная опция описывается как «подлежащая изменению».