Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

【Java11】javacでコンパイルせずにJavaを実行してみた

More than 1 year has passed since last update.

はじめに

本投稿はJava Advent Calendar 2018 の25日目の記事です。
初心者ではありますが、「参加することに意義がある!」の精神で、とりあえず空いていた枠に登録してしまいました。

最終日にも関わらず、薄い内容で申し訳ない気持ちもありますが初心者らしく、いざHelloWorld!

 ※2018/12/26更新:サ〇タ業務の都合上、書きかけで投稿してしまったため、一部内容を追加。

コンパイルせずにjavaを実行!?

Java11から、javacでコンパイルせずにjavaを実行できるという噂を聞きつけたため、HelloWorldしてみる。
ただし、ソースファイルが1つで完結する場合に限るなどの制限があるようなので、その辺も試してみる。

環境

OS:Windows 10
Java:Oracle Open JDK 11
コンソール:コマンドプロンプト

まずは普通のHelloWorldのみ

HelloJDK11.java

public class HelloJDK11 {
    public static void main(String[] args) {
        System.out.println("HelloWorld!");
    }
}

実行してみる

>java HelloJDK11.java
HelloWorld!

めでたく、コンパイルせずに実行できました。

HelloJDK11.javaが存在するディレクトリには、HelloJDK11.classは作成されていませんでした。

試しにjavacでコンパイルしてみる

>javac HelloJDK11.java

>java HelloJDK11
HelloWorld!

いつも通り、HelloJDK11.classが作成されました。

しかし、、、

>java HelloJDK11.java
エラー: アプリケーション・クラス・パスにクラスが見つかりました: HelloJDK11

どうやら、クラスパス上にclassファイルが存在する場合、javaファイルをjavaコマンドで実行するとエラーとなるようです。
classファイルを削除すると、元通りjava HelloJDK11.javaで実行可能になりました。

念のためにメソッド呼び出しをする

public class HelloJDK11 {

    public static void main(String[] args) {
        System.out.println("HelloWorld!");
        callMethod();
    }

    private static void callMethod() {
        System.out.println("CalledMethod!");
    }
}

実行

>java HelloJDK11.java
HelloWorld!
CalledMethod!

メソッド呼び出しも問題ありませんでした。
 ※先ほど作成されていたclassファイルは削除しています。

javaファイル名とクラス名を別名にする

HelloJDK11.java

public class SorryJDK11 {

    public static void main(String[] args) {

~先ほどと同様なので略~

}

javaファイル名:HelloJDK11.java
クラス名:SorryJDK11

実行とコンパイル

>java HelloJDK11.java
HelloWorld!
CalledMethod!

>javac HelloJDK11.java
HelloJDK11.java:1: エラー: クラス SorryJDK11はpublicであり、ファイルSorryJDK11.javaで宣言する必要があります
public class SorryJDK11 {
       ^
エラー1個

javaファイル名とクラス名が不一致だと、

コンパイル出来ないが、javaファイルのまま実行可能なようです。

Personクラスを書いてnewしてみる

HelloJDK11.java

public class HelloJDK11 {
    public static void main(String[] args) {
        Person suzuki = new Person("鈴木");
        System.out.println(suzuki.getName());
    }
}

class Person {
    // フィールド
    private String name;
    // コンストラクタ
    public Person(String name) {
        this.name = name;
    }
    // ゲッター
    public String getName() {
        return this.name;
    }
}

実行

> java HelloJDK11.java
鈴木

問題ありませんでした。

Personクラスを別ファイルに分割する

先ほどのHelloJDK11.javaをHelloJDK11.javaとPerson.javaの2ファイルに分割

>java HelloJDK11.java
HelloJDK11.java:7: エラー: シンボルを見つけられません
                Person suzuki = new Person("鈴木");
                ^
  シンボル:   クラス Person
  場所: クラス HelloJDK11
HelloJDK11.java:7: エラー: シンボルを見つけられません
                Person suzuki = new Person("鈴木");
                                    ^
  シンボル:   クラス Person
  場所: クラス HelloJDK11
エラー2個
エラー: コンパイルが失敗しました

コンパイルエラーが発生しました!

冒頭でも記述した制限事項

「1つのソースファイルで完結している必要がある。」による
コンパイルエラーが発生しました。

一応、javacでコンパイルすると、
>javac HelloJDK11.java

HelloJDK11.classとPerson.classの2ファイルが作成され、javaコマンドで実行も出来ました。

まとめ

新人研修の頃、毎回javacしてjavaしてたのが面倒だった記憶があるため、今回のJava11でのjavacなしで実行できるという動作に興味を持ち記事にしてみました。

JEP 330によると、別にJavaをスクリプト言語のようにコンパイルなしで実行できるようにすることが目的ではないようです。

シェバン(shellの1行目の#!/bin/shとか)としてJavaファイルをコマンド実行することが目的とのこと。
./HelloJDK11
みたいに実行できるらしいです。(今度試してみます。)

yaaka4
顧客先にてJavaのシステム開発を行っている。主に金融系。プログラムからは離れて管理とかの時期もあったが、現在はSpringを使ったフレームワーク開発チームに所属。 勉強会やQiitaに参加して技術力を向上させていきたい。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away