【Java入門目次】Javaを他言語と比較してみた（インタプリタ型、コンパイラ型、動的型付け、静的型付け）

#目的

Javaの学習を始めたばかりで、他言語との違いを理解したい。

**[概要と環境構築に関する記事はこちら](https://qiita.com/morioheisei/items/ef8eb5d75c07b4d280f4)**

Javaで学んだ事を何記事かに分けてアウトプットしていきたいと思っています。

・[変数と型](https://qiita.com/morioheisei/items/3d27e82d6cd88068dded)
・[型変換](https://qiita.com/morioheisei/items/28ab5fd69570e01cd317)
・[変数のスコープ](https://qiita.com/morioheisei/items/c56ab32b68ce92d32206)
・[文字列の操作](https://qiita.com/morioheisei/items/e58adadd8535971b69be)
・[配列の操作](https://qiita.com/morioheisei/items/b6acbb1b0c07b40e7f56)
・[演算子](https://qiita.com/morioheisei/items/63088c61e8234dc1f7f5)
・[条件分岐](https://qiita.com/morioheisei/items/194cdc73a29bddade0a4)
・[繰り返し処理](https://qiita.com/morioheisei/items/e686e33b60c6a60e87f0)
・クラスについて（準備中）
・抽象クラス（準備中）
・インターフェース（準備中）
・カプセル化（準備中）
・モジュールについて（準備中）
・[例外処理について](https://qiita.com/morioheisei/items/d25d2b67e7530c1aab9d) 
・[ラムダ式について](https://qiita.com/morioheisei/items/2bfcc3d8d8440b00e6a9)
・[Stream APIについて](https://qiita.com/morioheisei/items/3a7be38b4d3ef712ccb2)


次回は[変数と型](https://qiita.com/morioheisei/items/3d27e82d6cd88068dded)を確認していきます。
今回はJavaと他言語との違いをざっくり２点確認していきます。

#①プログラムを実行する方法

コンピューターは0と1で書かれた機械語しか実行、理解できない。
プログラミング言語で書かれたソースコードも機械語に変換（翻訳）しなければならない。

##Javascript、PHP、Rubyなど
`インタプリタ言語`と呼ばれる。
プログラミング言語で書かれたソースファイルを、
コンピューターが認識出来るように１行ずつ変換しながら実行していく。

>プログラムを書いて
>↓（機械語に翻訳）
>実行する
>↓
>プログラムを書いて
>↓（機械語に翻訳）
>実行する



```php:Hello.php
<?php
  echo "Hello World";
?>
```

```terminal:Terminal
$ php Hello.php
Hello World ←実行され出力された！
```

##Java
`コンパイラ言語`と呼ばれる。
プログラミング言語で書かれたソースファイルを、一旦全て機械語に変換（翻訳）して別ファイル(クラスファイル)を生成する。
そして実行はJVM（Java Virtual Machine）がまとめて行う。

>プログラムを書いて
>↓コンパイル（機械語に翻訳）
>クラスファイルを生成
>↓
>実行する

```Java:Hello.java
class Hello {
  public static void main(String[] args) {
    System.out.println("Hello World");
  }
}
```
ソースファイルをjavacコマンドでコンパイルしてクラスファイルを作成。

```:Terminal
$ javac Hello.java
$ ls
Hello.java     Hello.class ←作成された！
```

クラスファイルをjavaコマンドで実行してHello Worldを出力する。
`.classの拡張子はつけない。`

```:Terminal
$ java Hello
Hello World ←出力された！
```

##プログラムを実行する方法まとめ

**インタプリタ型言語**

・コンピュータが実行するときにソースファイルに書かれているプログラミング言語を機械語に変換して実行する。

・インタプリタ型言語は一々コンパイルをする必要がないので、面倒な手続きが一つ省ける。

**コンパイラ型言語**

・プログラミング言語で書かれたソースファイルを機械語が読み取れるように、コンパイルを行ったもの(クラスファイル)をあらかじめ用意しておく。だからコンピュータが処理を実行するときにはコンパイルを行う必要がない。

・コンピュータの処理速度ということでいえば、一度全てのコードを機械語にしているコンパイラ型言語の方が高速である。


#②データ型の指定

##Javascript、PHP、Rubyなど
`動的型付け言語`と呼ばれる。
変数名や関数の引数や返り値にどのような値が入ってくるか特に決まっていない。（決めずに宣言できる）

```JavaScript:test.js
let str = "おはよう";
console.log(str); // おはよう
str = 2020;
console.log(str); // 2020
```
元々は文字列を入れるための変数名「str」であったが、2020という数値も代入出来てしまいます。

```JavaScript:test.js
// 数字を足し算して、結果を返すための関数
function sumNumber(a, b) {
  return a + b;
}
console.log(sumNumber(1, 1)); // 2
console.log(sumNumber("Hello", "World")); // HelloWorld
```
元々は、二つの数字を足した結果を返したかった関数名「sumNumber」であったが、
文字列のHelloとWorldを足して返す事も出来てしまいます。

意図しない使い方も出来てしまうというデメリットがありますね。


##Java
`静的型付け言語`と呼ばれる。
変数名や関数の引数や返り値に明示的に型の宣言をする。
宣言されたその型以外のデータでは扱えない。

先程と同じようにコードを書いていきます。

```Java:Main.java
class Main {
  public static void main(String[] args) {
    String str = "おはよう";
    System.out.println(str); // おはよう
    str = 2020; // Type mismatch: cannot convert from int to String
    System.out.println(str);
  }
}
```
文字型のデータが入る変数名「str」に、数値の2020を代入しようとするとエラーが発生します。
正しくは...

```Java:Main.java
class Main {
  public static void main(String[] args) {
    String str = "おはよう";
    System.out.println(str); // おはよう

    // strに文字列の「こんばんは」を代入
    str = "こんばんは";
    System.out.println(str); // こんばんは

    // int型と指定した変数名「year」に2020を代入
    int year = 2020;
    System.out.println(year); // 2020
  }
}
```

関数の場合も同様です。

```Java:Main.java
class Main {
  public static void main(String[] args) {
    System.out.println(sumNumber(1, 1)); // 2
    System.out.println(sumNumber("Hello", "World")); // The method sumNumber(int, int) in the type Main is not applicable for the arguments (String, String)
  }

  // 第一引数、第二引数ともにint型を受け取り、返り値もint型の関数名「sumNumber」を定義
  public static int sumNumber(int a, int b) {
    return a + b;
  }
}
```

JavaScriptでは文字も数値でもどちらでも渡してよかったのに、Javaではエラーが発生します。
int型のデータを受け取る関数なのに、文字列を渡しているからです。

プログラム作成者の意図通り実行することが出来ますし、もし間違いが発生していたらプログラム実行前に気づく事が出来るメリットがあります。


#おわりに

今まで動的型付け言語しか学習してこなかったため、変数宣言のたびにデータ型を指定するのは驚きでした。
次は、[変数と型](https://qiita.com/morioheisei/items/3d27e82d6cd88068dded)を掘り下げていきます。