こんにちは、@p1ass です。

この記事は、他のプログラミング言語は書いているが Java はそんなに書いていない/忘れた私が Java をキャッチアップするために得た知識をまとめたものです。 ある程度他の言語を書いている人であれば文法周りは困らないと思うので、エコシステム周りを重点的に書いています。

1. ローカル開発環境構築

現在の環境は次の通り。

項目
OSmacOS Big Sur
Java バージョン17
Gradle バージョン7,2

事前知識: Java 自体の開発とディストリビューション

事前知識: JAVA_HOMEとは

選択肢 1: /usr/libexec/java_home を使う

java_home コマンドを使うことでインストールされている Java のバージョンの一覧を取得できる。

$ /usr/libexec/java_home -V
Matching Java Virtual Machines (1):
    11.0.3 (x86_64) "AdoptOpenJDK" - "AdoptOpenJDK 11" /Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home

-vオプションで利用するバージョンを指定できる。

$ /usr/libexec/java_home  -v 11
/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home

JAVA_HOME の設定は次のようにすれば良い。

$ export JAVA_HOME=`/usr/libexec/java_home -v 11`

$ java --version
openjdk 11.0.3 2019-04-16
OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.3+7)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.3+7, mixed mode)

java_home コマンドの注意点として、同じバージョンの違うディストリビューションは指定できない。 同じバージョンの別ディストリビューションを切り替えたい場合は後述する jenv を使う。

選択肢 2: jenv を使う

jenv は Java のバージョンを切り替えて、自動で JAVA_HOMEを設定してくれるライブラリ。 ディストリビューションは自分でインストールする必要がある点に注意する。 自分の環境は jenv でセットアップしている。

インストールの仕方は README を参照。

Amazon Corretto のインストール

いろんなディストリビューションがあるが、今回は Corretto を使う。 pkg を落としたら、 jenv add して jenv global で切り替える。

2. エディターセットアップ

IntelliJ IDEA を使う。

Community 版なら無料で使える。使い方は公式の日本語ドキュメントを参照。

設定せずに先程インストールした Corretto が選択できるようになっているはず。

3. Gradle プロジェクトを作成

Gradle は Java で使われる OSS のビルドツール。 Maven が使われることもあるが、周りは Gradle を使っている人が多いので、ここでは Gradle を使う。

intellij.png

IntelliJ でプロジェクトを作成するときに Gradle を選べば、良い感じのプロジェクトを作ってくれる。

記事執筆時点では、Java17 のリリース直後だったので、次のようなエラーが出てしまった。

Unsupported Java.
Your build is currently configured to use Java 17 and Gradle 7.1.

Possible solution:
 - Use Java 16 as Gradle JVM: Open Gradle settings
 - Open Gradle wrapper settings, change `distributionUrl` property to use compatible Gradle version and reload the project

./gradle/wrapper/gradle-wrapper.propertiesdistributionUrlのバージョンを 7.2 にあげて、 ./gradle wrapperする。

# ./gradle/wrapper/gradle-wrapper.properties
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

その後、IntelliJ で Shift 2 回押して、Reload All Gradle Projects をすれば直った。

src/main/java/helloworld/HelloWorld.javaを作成して、Hello World する。

package helloworld;

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

実行はエディターの UI やショートカット、もしくはターミナルから実行できる。

$ ./gradlew build

BUILD SUCCESSFUL in 541ms
3 actionable tasks: 3 up-to-date

$ java -cp build/classes/java/main helloworld.HelloWorld
Hello World

Gradle から直接実行する場合は build.gradleを変更する。

// build.gradle
plugins {
    id 'application' // 'java' から切り替える
}

application {
    mainClass = 'helloworld.HelloWorld' // エントリーポイントを指定
}
$ ./gradlew run

> Task :run
Hello World

BUILD SUCCESSFUL in 532ms
2 actionable tasks: 1 executed, 1 up-to-date

4. 基本文法を学ぶ

ある程度他のオブジェクト指向の言語を書いた人ならスルッと入れるので、サクッと流す。

5. Java8 以降に追加された文法・ライブラリを学ぶ

Java8 以前と以降でだいぶ異なるところがある。 適当にググると古いやり方が出てきたりするので注意する。

  • Stream
    • map や filter といった高階関数系のメソッドやラムダ式など
  • Optional
    • Null を扱いやすくするクラス
  • var を用いた型推論
    • 変数定義時に毎回型を省略できる
  • java.time.LocalDateなど新しい日時クラス
    • 以前は java.util.Datejava.time.Calendarが使われていたらしい
    • ネットで日時系の処理を調べると古いやり方が引っかかたりするので注意

6. サードパーティライブラリを使う

Gradle でサードパーティライブラリを扱う仕組みは公式ドキュメントに書かれている。

リポジトリの指定

Java のライブラリの多くは Maven Central というリポジトリにホスティングされている。 build.gradle で Maven Central から依存を解決するように指定する。(最初から書かれている場合もある)

repositories {
    mavenCentral()
}

依存関係の記述

build.gradle の dependencires ブロックに記述する。

今回は JSON ライブラリである Jackson をインストールする。 implementation 等の意味は先ほどの Gradle の公式ドキュメントだけでなく、Android の公式ドキュメントなどにも書かれている。

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.0'
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.12.5' // 追加
}
package helloworld;

// importする
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class HelloWorld {
    public static void main(String[] args) throws JsonProcessingException {
        var user = new User();
        user.id = "p1ass";
        user.name = "ぷらす";

        var mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(user));
    }

    public static class User {
        public String id;
        public String name;
    }
}
$ ./gradlew run

> Task :run
{"id":"p1ass","name":"ぷらす"}

7. 雑に有名所のサードパーティライブラリを知っておく

必要になったときにググれるように、ある程度インデックスを貼っておく。

8. スタイルガイドを知る

より良い書き方を学ぶ。

9. Linter・Formatter

お好みで設定する。

Linter

Formatter

10. Gradle のマルチプロジェクトを使って大規模なプロジェクトを作る

1 つのプロジェクトの中に複数のプロジェクトを作成できる機能。 API・バッチ・共通ライブラリをそれぞれ別のプロジェクトにしつつ、1 つのリポジトリで管理できる。

自分で 1 からプロジェクトを作ることは少ないかも知れないが、既存のプロジェクトがマルチプロジェクトになっていることは結構あるので、「build.gradle が複数あるんだけど!」ってならないために知っておくと良さそう。

おわりに

最初の数日でキャッチアップするならこのくらいなのではないでしょうか。