インターネット上のほとんどのウェブサイトはこう言います:
"
javac
コマンドを使用して.Java
ファイルをコンパイルします。その後、Java
コマンドを使用して実行します"
しかし、今日、javac
なしでJavaプログラムを実行しようとしましたが、奇妙な結果が得られました。
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
コマンドが必要なのですか?
My 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)
Java 11の前に、コードを実行するには、最初にコンパイルする必要があります。次に実行できます。以下に例を示します。
javac test.Java
java test
Java 11なので、まだjavac
+ Java
を実行できます。または、Java
を単独で実行してコンパイルし、自動実行することもできます。コード。.class
ファイルが生成されます。次に例を示します。
Java test.Java
Java -help
、許可されたさまざまな使用法が表示されます。私のマシンでは次のようになります。最後のものは、あなたが遭遇したものです:Java [options] <sourcefile> [args]
「単一のソースファイルプログラムを実行する」。
$ Java -help
Usage: Java [options] <mainclass> [args...]
(to execute a class)
or Java [options] -jar <jarfile> [args...]
(to execute a jar file)
or Java [options] -m <module>[/<mainclass>] [args...]
Java [options] --module <module>[/<mainclass>] [args...]
(to execute the main class in a module)
or Java [options] <sourcefile> [args]
(to execute a single source-file program)
UPDATE:
@BillKが指摘したように、OPは次の質問もしました。
なぜjavacコマンドが必要なのですか?
javac
が必要な理由は、.class
ファイル。これにより、現在のようにコードを作成、テスト、配布、実行、共有などすることができます。 JEP 3 の動機は、「Javaの学習の初期段階、および小さなユーティリティプログラムを記述するとき」を他の既存の用途を変更せずに簡単にすることでした。
実行している場合Java 11、単一ソースファイルの実行を許可する新しい機能があります。単一ソースコンパイラは、クラス名とファイル名の点でより無差別です。 、それはあなたが実行することができますが、正常にコンパイルできない方法です。
以前のバージョンのJavaを使用している場合の場合、現在のhello.Javaは、特にクラス名周辺のコンパイルエラーのためにコンパイルされません。したがって、コードをコンパイルしないため、Java hello.Javaを呼び出してコードをコンパイルする方法はまったくありません。
Javaコマンドを実行するときに、以前にコンパイルされたコードを実行していた可能性が最も高いようです。
このエラーが発生する理由に答えるには、ファイルのクラス名がファイルのbasename
と一致する必要があります。
このコードを従来のjavac
に対して機能させるには、2つのオプションがあります。 Java
シーケンス:
クラスの名前をpublic class Hello
に変更するか、
hello.Java
の名前をmyclass.Java
に変更します。
Java 11のJava
インタープリターは、この要件を課しません。main
を含むクラスは、それがこれは主に、初心者向けの学習プロセスを容易にし、シバンで「Javaスクリプト」を許可することを目的としています( ref。 )。
はい、しかしあなたがおそらく意味する方法ではありません。
javac
コマンドを使用して.Javaファイルを.classファイルにコンパイルすると、出力はバイトコードと呼ばれるものになります。バイトコードは、Java Virtual Machineの仕様に基づいた理論上のCPUのマシンコード(ネイティブ命令)です。
この仮想CPU仕様は、仕様が作成された時点で一般的だったCPUの種類の平均のようなものです。このため、多くの異なるタイプのCPUに近いため、同じJava .classファイルを複数のCPUタイプで実行しやすくなります。
Javaが最初に起動されたとき、Java
コマンドは.classファイルを読み取り、バイトコード命令を一度に1つずつ解釈し、CPUの同等のネイティブ命令にマップしますジャストインタイム(JIT)コンパイルをJava Runtime。に追加しました。
JITを使用すると、Java
コマンドはバイトコードを取得し、実行中のCPUのネイティブ命令に再度コンパイルします。モダンJavaランタイムは、バックグラウンドでJITコンパイル中にバイトコードの解釈を開始し、準備ができたときにコンパイル済みネイティブ命令に切り替え、実行中のアプリケーションのプロファイルを作成し、別のバイトコードを再コンパイルします最高のパフォーマンスを得るための最適化。
編集(下の有権者をなだめるため):
したがって、特定の場合(v11より新しいJREを実行している場合)、コードは(少なくとも)2回コンパイルされます。