コマンドラインでJavaのコンパイルや実行

はじめに
この記事はこれからJavaを勉強する方に向けた私自身の理解している内容の記録です。

Javaの機能や記載方法についてを、下記のリストに分けて記載していきます。

・[変数と型、型変換](https://qiita.com/pitan109/items/2538b234a2c6e20c037f)
・[変数のスコープ](https://qiita.com/pitan109/items/b30589bc4c2e8169734c)
・文字列の操作（準備中）
・配列の操作（準備中）
・演算子（準備中）
・条件分岐（準備中）
・繰り返し処理（準備中）
・[例外処理](https://qiita.com/pitan109/items/c9910edddc007126df41)
・クラスについて（準備中）
・抽象クラス（準備中）
・インターフェース（準備中）
・カプセル化（準備中）
・モジュールについて（準備中）

ただこの記事ではリストとは別で、記事の中でも行なっていたコマンドラインでの実行の記載を行なっていきます。

##コマンドラインとは
最初私もこのワードを聞いた時にこのワードがわからなかったのですが、windowsでのコマンドプロンプト、macでのターミナルで表示される1行のことをコマンドラインというみたいです。
この記事ではJavaがインストールされている前提で、macのターミナルとwindowsのコマンドプロンプトでJavaを実行して見ようと思います。環境構築については以前私があげた記事もあるので、参考にしていただければと思います。[Javaの開発環境](https://qiita.com/pitan109/items/77296189c6b68e26d5d4)

コンパイルするにはコードがいるので、HelloWorldを作って見ました。

```java
class Test{
    public static void main(String args[]){
        System.out.println("Hello World!");
    }
}
```

プログラムの学習で最初によく出るHello World文です。Hello Worldを出力するシンプルなコードです。

##コンパイル
上記のコードをコンパイルしましょう。ちなみにコンパイルというのは簡単にいうと記載されているコードをコンピュータが読めるような文章に書き換えることです。

```
$ javac コンパイルしたいjavaファイル
```

testフォルダ内に上記のコードを記載したtest.javaをコンパイルします。

```
test$ javac test.java
```

このコマンドでtest.javaを読み込み、コード内にあるクラスを確認し、クラスファイルを生成します。ちなみにjavaファイル内に複数のクラスがある場合は、全てのクラスファイルを生成してくれます。

```java
class Test{
    public static void main(String args[]){
        System.out.println("Hello World!");
    }
}

class Sample{}

class Mikan{}
```

SampleクラスとMikanクラスを作成しましたが、中には何も記載していません。このコードをコンパイルします。

```
test$ javac test.java
```

これでTest.class、Sample.class、Mikan.classの3つのクラスファイルが生成できました。

##実行

```
$ java 実行したいクラスファイル名
```

このコマンドでクラス内のmainメソッド内を実行します。
上記をコマンドプロンプト(ターミナル)で入力してみましょう。

```
test$ java Test
```

結果は

```
Hello World!
```

Testクラス内、mainメソッド内にある出力文を表示しています。

コマンドプロンプト(ターミナル)での実行は以上ですが、１つ気をつけなければならないことがあります。

mainメソッド内を実行するので、mainメソッドがなければコンパイルはうまくできてもエラーになります。

```java
class Test{}
```

このコードをコンパイルしますが、エラーにならずクラスファイル(Test.class)を生成できます。

```
test$ javac test.java
```

作成したファイルで実行して見ましょう。

```
test$ java Test
```

実行するとエラーが出ました。

```
エラー: メイン・メソッドがクラスTestで見つかりません。次のようにメイン・メソッドを定義してください。
   public static void main(String[] args)
```

実行するクラスに、メインメソッドが必要なのを忘れないようにしましょう。

##デバッグ実行
コマンドラインでもデバッグ実行ができます。デバッグ実行とは簡単にいうと、実装されているプログラムがどのように動いているかの確認をすることです。実際にコマンドライン上で行なって見ましょう。

test.java

```java
class Main{
    int instans = 60;
    static int global = 95;

    static void debug(){
        System.out.println();
        System.out.println("デバッグ実行");
    }

    void print(){
        System.out.println("print()");
    }

    public static void main(String args[]){
        Main.debug();
        System.out.println("main start");

        int x = 50;

        String str = "文字型";

        Main m = new Main();

        x = 100;

        str = "文字型変換";

        m.print();

        System.out.println("main end");
    }
}
```

上記記載のjavaファイルをコンパイルしますが、デバッグ実行をしたい時は気をつけなければいけないことがあります。

```
$ javac -g test.java
```

コンパイル時のオプションに-gを設定しましょう。これでJDK標準搭載のjdbというデバッグ機能が使えます。
さっそくjdbを起動しましょう。

```
$ jdb Main
```

```
> 
```

上記矢印に様々なコマンドを打つことで、デバッグを行えますが、まずは動作させないと何もできないので、runコマンドを入れて見ましょう。これでvmが動作します。

```
> run
```

```
VMが開始されました: 
デバッグ実行
main start
print()
main end
```

ただrunコマンドだけでは、実行するだけでjdbが終了してしまいます。そこであらかじめブレークポイントをセットしておきます。ブレークポイントとは、実行中に動作を止める場所のことで、その場所をコマンドで指定できます。

```
> stop in Main.debug
```

mainメソッド内で動作しているdebugメソッドの動作開始時にコマンド入力状態になると思います。実際に実行して見ましょう。

```
> run
```

```
VMが開始されました: 遅延したブレークポイントMain.debugの設定

ヒットしたブレークポイント: "スレッド=main", Main.debug()、行=8 bci=0
8            System.out.println();
main[1] 
```

この状態は、プログラムをこの場所で止めている状態というのを表しています。もっと詳しく見るため、実行箇所確認コマンドのlistを使って見ましょう。

```
main[1] list
```

```
4        int instans = 60;
5        static int global = 95;
6    
7        static void debug(){
8 =>         System.out.println();
9            System.out.println("デバッグ実行");
10        }
11    
12        void print(){
13            System.out.println("print()");
```

と表示されます。debugメソッドの出力のところで止まっている状態というのがわかりやすくなったと思います。

##ステップ実行
上記のコードで停止しているプログラムを進めていきましょう。このステップ実行ではコードを一行づつ進めることができます。上記に続いて記載していきましょう。

```
step
```

```
ステップが完了しました: "スレッド=main", Main.debug()、行=9 bci=6
9            System.out.println("デバッグ実行");
```

ステップ実行を行いました。再びlistを見て見ます。

```
5        static int global = 95;
6    
7        static void debug(){
8            System.out.println();
9 =>         System.out.println("デバッグ実行");
10        }
11    
12        void print(){
13            System.out.println("print()");
14        }
```

ステップ実行前は8行目で止まっていたのが9行目になっています。1行ずつ進めているということになります。
さらにステップ実行を行い、list表示をしましょう

```
step
```

```
> デバッグ実行
```

ステップ実行したことで、出力の処理が動いています。

ステップ実行後にlistを確認します。

```
list
```

```
6    
7        static void debug(){
8            System.out.println();
9            System.out.println("デバッグ実行");
10 =>     }
11    
12        void print(){
13            System.out.println("print()");
14        }
15    
```

また一行コードを読み進めているのがわかりやすいと思います。

ここまではステップ実行のコマンドや動作を紹介しましたが、ここからはステップ実行の有用性についての解説をします。

まずはlistで実行待ちが下記になるまでステップ実行を行いましょう。

```
20            int x = 50;
21    
22            String str = "文字型";
23    
24 =>         Main m = new Main();
25    
26            x = 100;
27    
28            str = "文字型変換";
29    

```

ここまでの処理が動作している時点で変数のxとstrにそれぞれ値を入れています。このコードの後に別の値を代入していますが、このステップ実行中では、今時点での変数の値の表示が行えます。

ローカル変数の値を表示するlocalsコマンドを使います。

```
main[1] locals 
```

```
ローカル変数:
x = 50
str = "文字型"
```

このようにローカル変数の今時点での値が表示されています。

このコードを進めて行くと値を書き換えるので、まずは代入終了までステップ実行していきましょう。

```
26            x = 100;
27    
28            str = "文字型変換";
29    
30 =>         m.print();
31    
32            System.out.println("main end");
33        }
34    }
```

この時点でxとstrにはそれぞれ値を置き換えています。もう一度localsコマンドで確認して見ましょう。

```
main[1] locals
```

```
ローカル変数:
x = 100
str = "文字型変換"
m = instance of Main(id=422)
```

xとstrの値変更が今のステップ実行の段階では動作しているので、値が書き換わっています。また、変数mを宣言し、インスタンスを代入しているので、新たに変数mも表示されています。

このように実行中でプログラムが見ている時点での値の状態がわかるので、動作確認をするときに、任意のタイミングで自分の意図した値が入っているかを確認することができます。

ちなみにローカル変数を１つ確認したい時やインスタンス変数、static変数の中身もprintコマンドを使うと確認できます。

ローカル変数

```
main[1] print str
```

```
str = "文字型変換"
```

インスタンス変数

```
main[1] print m.instans
```

```
m.instans = 60
```

static変数

```
main[1] print Main.global
```

```
Main.global = 95
```

##終わりに
この記事ではコマンドプロンプト(ターミナル)でJavaのコンパイル、実行、デバッグ実行中のステップ実行を行なってみました。Javaをインストールしたらできるようになるので、一度試して見てはいかがでしょうか？

ただ、デバッグ実行はコマンドラインで行うよりは、開発環境等で導入されているツールの方が使いやすいと思うので、
eclipseでデバッグ実行を行う下記の記事も参考にしてみてください。

[IDEでのデバッグ実行](https://qiita.com/pitan109/items/c87aa963fe25e7825f96)