Большинство сайтов в интернете говорят:
«используйте
javac
команду для компиляции.java
файла. Затем запустите его с помощьюjava
команды»
Но сегодня я попытался запустить Java-программу без, javac
и я получил странный результат.
Вот содержимое файла с именем hello.java
:
public class Myclass {
public static void main(String[] args){
System.out.println("hello world");
}
}
Затем я побежал:
$ javac hello.java
Что дает мне эту ошибку:
hello.java:1: error: class Myclass is public, should be declared in a file named Myclass.java
public class Myclass {
^
1 error
Но когда я запускаю его без javac
команды, он выполняется без ошибок.
$ java hello.java
hello world
Имеет ли java
команда также скомпилировать программу? Если да, зачем нам javac
команда?
Версия моего Java:
openjdk version "12.0.2" 2019-07-16
OpenJDK Runtime Environment (build 12.0.2+10)
OpenJDK 64-Bit Server VM (build 12.0.2+10, mixed mode)
Myclass.java
и затем из командной строки скомпилируйте его следующим образом,javac Myclass.java
а затем запустите его следующим образомjava Myclass
.javac
сих пор используются для компиляции , если вы не хотите , чтобы развернуть исходный код, или у вас есть более чем один файл ( документация поjava
: для варианта исходного файла используется только для запуска одной программы исходного файла.)javac
компилирует исходный код Java в специфический интерпретируемый байт-код JVM, иjava
команда загружает его в ClassLoader JVM.Ответы:
До Java 11 для запуска вашего кода вы должны сначала скомпилировать его, а затем запустить его. Вот пример:
Начиная с Java 11, вы все равно можете делать
javac
+java
или запускатьjava
сам, чтобы скомпилировать и автоматически запустить ваш код. Обратите внимание, что.class
файл не будет создан. Вот пример:Если вы побежите
java -help
, вы увидите различные разрешенные способы использования. Вот как это выглядит на моей машине. Последнее, с чем вы столкнулись:java [options] <sourcefile> [args]
«выполнит одну программу с исходным кодом».ОБНОВИТЬ:
Как отмечает @BillK, ОП также спросил:
Причина, по которой мы нуждаемся,
javac
состоит в том, чтобы создавать.class
файлы, чтобы код можно было создавать, тестировать, распространять, запускать, передавать и т. Д., Как это делается сегодня. Мотивация для JEP 330 состояла в том, чтобы облегчить «ранние этапы изучения Java и при написании небольших служебных программ» без изменения каких-либо других существующих применений.источник
1.
в1.8
в новых версиях)javac
.Если вы используете Java 11, есть новая функция, которая позволяет выполнять файл с одним исходным кодом. Компилятор с одним исходным кодом более разнороден с точки зрения имени класса по сравнению с именем файла, поэтому вы можете работать, но не успешно компилировать.
Если вы используете предыдущую версию Java, то ваш текущий hello.java не компилируется из-за ошибок компиляции, в частности, вокруг имени класса. Таким образом, абсолютно невозможно, чтобы вызов java hello.java компилировал ваш код, потому что он не компилируется.
Наиболее вероятно, что вы выполняли какой-то ранее скомпилированный код при выполнении команды java.
источник
Чтобы ответить, почему дается эта ошибка, имя класса для файла должно совпадать с именем файла
basename
.У вас есть два варианта, чтобы этот код работал для традиционного
javac
;java
последовательность:Переименуйте класс в
public class Hello
илиПереименовать
hello.java
вmyclass.java
.java
Интерпретатор Java 11 не навязывает это требование. Класс, который содержит,main
может иметь любое имя, если это первый класс в файле. Это было главным образом предназначено, чтобы облегчить процесс обучения для начинающих, и позволить "сценарии Java" с Шебангом ( ссылка ).источник
Да, но не так, как вы, вероятно, имеете в виду.
Когда вы используете
javac
команду для компиляции файла .java в файл .class, на выходе получается нечто, называемое байт-кодом. Байт-код - это машинный код (собственные инструкции) для теоретического ЦП, основанного на спецификации виртуальной машины Java.Эта спецификация виртуального ЦП является своего рода средним числом типов ЦП, которые были распространены во время написания спецификации. Из-за этого он близок к множеству разных типов процессоров, что облегчает запуск одних и тех же файлов Java .class на нескольких типах процессоров.
При первом запуске Java
java
команда считывала файл .class и интерпретировала инструкции байт-кода по одной, а затем сопоставляла их с эквивалентной встроенной инструкцией для того процессора, на котором она фактически выполнялась. Это работало, но не было особенно быстро. Для улучшения этого JIT-компиляция была добавлена в Java Runtime.С помощью JIT
java
команда берет байт-код и снова компилирует его в исходные инструкции для процессора, на котором работает. Современные среды выполнения Java, как правило, начинают интерпретировать байт-код во время компиляции в фоновом режиме JIT и переключаются на скомпилированные нативные инструкции, когда он будет готов, а также будут профилировать работающее приложение, а затем заново компилировать байт-код с другой оптимизацией, чтобы получить наилучшую возможную производительность.РЕДАКТИРОВАТЬ (чтобы успокоить избирателей):
Таким образом, в вашем конкретном случае (поскольку вы используете JRE новее, чем v11), код компилируется (как минимум) дважды
источник
mixed-mode
выходные данные версии