Java Tutorial

1.はじめに

はじめまして。山下です。

今日はサクッとJavaチュートリアルやっていきましょう。

実際に手を動かして実行してみてね。

お勧めの開発環境は、IntelliJ IDEAです。

インストールしてみてね。

Java

2.Hello, World

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, World");
    }
}

上記のコードをIDEより実行すると下の標準出力にHello, Worldと出力されることが確認できる。

実行方法は、IDE上部の実行ボタン(Shift + F10)もしくはデバッグ実行(Shift + F9)で行える。

System.out.println は、括弧の中に渡した内容を標準出力(コンソール)に表示するための命令だ。

IDE実行

3.プログラミングの物理法則

プログラミングには大事な物理法則が存在している。

  1. 必ずエントリポイント(mainメソッド)からプログラムが開始する。
  2. エントリポイント(mainメソッド)を抜けるとプログラムが終了する。
  3. プログラムは上から下に実行される。

初学者はこのことを必ず意識して欲しい。

これはJavaに限ったことではない。

4.簡単な計算をしてみよう。

以下のプログラムは、私の10年後の年齢を計算している。

プログラミングでは、四則演算が可能である。

public class Main {
    public static void main(String[] args) {
        System.out.println(43 + 10);
    }
}

実行してみると標準出力として53という文字が表示される。

ただこの出力だけでは何の数値かわかりづらい。もう少し説明的に出力してみよう。

public class Main {
    public static void main(String[] args) {
        var myAge = 43 + 10;
        System.out.println("10年後、私は" + myAge + "歳になります。若い!");
    }
}

この出力でユーザは、状況が掴みやすくなった。

先ほどのプログラムと違い、変数myAgeを宣言して計算結果を保存している。

またvarという型推論機能をつかっている。型推論は右辺の値からどの型を定義するかコンパイラが判断してくれるのだ(Java 10以降で使用可能)。

なので以下のように型推論を使わない書き換えもできる。

public class Main {
    public static void main(String[] args) {
        int myAge = 43 + 10;
        System.out.println("10年後、私は" + myAge + "歳になります。若い!");
    }
}

int myAge = 43 + 10;には2つの演算子が登場する。

=(イコール)と+(プラス)だ。

その他にもたくさんあるのだが実行する優先順位がある。

下の表をみると=を実行する優先順位は、一番したなので先に+演算子を行う。

43と10を足した結果をmyAgeに代入するということになる。

演算子優先順位

int a = 2 + 3 * 4;       // 3*4 が先 → 14
int b = (2 + 3) * 4;     // () で優先度を変える → 20
boolean c = 1 + 2 == 3;  // 1+2 が先、次に == → true
int d = 10 - 4 - 2;      // 左から順に → 4(左結合)

優先順位を全部覚える必要はない。括弧で括れば良い。

5.プリミティブな型(基本データ型)

Javaにはプリミティブな型が存在する。プリミティブな型って何だよ。

値をとるデータ型と思っていただければよい。

プリミティブな型

プリミティブな型に対応するクラスも存在する。

// プリミティブ型:値を直接持つ
int a = 10;

// オブジェクト型(参照型):値のある場所を指す
Integer b = 10; // オートボクシング(推奨)
String s = "Hello";

プリミティブは軽くて速い、オブジェクトはメソッドが使えて便利というトレードオフがある。

オブジェクトはインスタンスの生成に時間がかかる。

以下のような例でスピードを比較してみよう。

import java.time.Instant;
import java.time.Duration;

public class Main {
    public static void main(String[] args) {
        int[] numbers = new int[10000000];
        Instant start = Instant.now();
        for (int i = 0; i < 10000000; i++) {
            numbers[i] = i;
        }

        Instant end = Instant.now();
        Duration elapsed = Duration.between(start, end);
        System.out.println("経過時間: " + elapsed.toMillis() + "ms");
    }
}

1000万個の数値を配列に入れて初期化を行う。

プリミティブ型の場合コレクションに入れることはできないため配列にセット。

出力された時間は「経過時間: 13ms」と出力された。

では次は対応するオブジェクトでやってみよう。

オブジェクト配列への代入では、プリミティブ型からオブジェクト型への自動変換(オートボクシング)が毎回発生するため、処理が遅くなる。

import java.time.Instant;
import java.time.Duration;

public class Main {
    public static void main(String[] args) {
        Integer[] numbers = new Integer[10000000];
        Instant start = Instant.now();
        for (int i = 0; i < 10000000; i++) {
            numbers[i] = i; // オートボクシングが毎回発生
        }

        Instant end = Instant.now();
        Duration elapsed = Duration.between(start, end);
        System.out.println("経過時間: " + elapsed.toMillis() + "ms");
    }
}

出力された時間は「経過時間: 282ms」と出力された。

※実行環境によって結果は異なります。

予想より早かったな。