diff --git a/README.md b/README.md index 744776f..b57b5bf 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,10 @@ JAVA Basic Code ## 実行方法 +### JDK + ```sh +cd dockerfile/jdk docker compose up -d docker compose exec -it app bash ``` @@ -14,4 +17,11 @@ docker compose exec -it app bash ```sh javac Hello.java java Hello -``` \ No newline at end of file +``` + +### Maven + +```sh +docker compose up -d +docker compose exec -it dev bash +``` diff --git a/docker-compose.yaml b/docker-compose.yaml index 793dae0..6ecfd93 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,12 +1,14 @@ -version: "3.9" - +# compose.yaml services: - app: - image: eclipse-temurin:21-jdk - working_dir: /app + dev: + image: maven:3.9-eclipse-temurin-21 + working_dir: /workspace volumes: - - ./src:/app # ← bind mount(ホストの ./src を /app に) + - ./:/workspace + - m2:/root/.m2 # 依存キャッシュ tty: true stdin_open: true command: bash - # # command: bash -lc "javac Hello.java && java Hello" \ No newline at end of file + # command: bash -lc "mvn -DskipTests package && bash" +volumes: + m2: \ No newline at end of file diff --git a/Dockerfile b/dockerfiles/jdk/Dockerfile similarity index 100% rename from Dockerfile rename to dockerfiles/jdk/Dockerfile diff --git a/dockerfiles/jdk/docker-compose.yaml b/dockerfiles/jdk/docker-compose.yaml new file mode 100644 index 0000000..793dae0 --- /dev/null +++ b/dockerfiles/jdk/docker-compose.yaml @@ -0,0 +1,12 @@ +version: "3.9" + +services: + app: + image: eclipse-temurin:21-jdk + working_dir: /app + volumes: + - ./src:/app # ← bind mount(ホストの ./src を /app に) + tty: true + stdin_open: true + command: bash + # # command: bash -lc "javac Hello.java && java Hello" \ No newline at end of file diff --git a/docs/java_construction.md b/docs/java_construction.md new file mode 100644 index 0000000..4cb9f59 --- /dev/null +++ b/docs/java_construction.md @@ -0,0 +1,222 @@ +# Java SE構文(8〜21の主要差分まとめ) + +この文書は、Java SE 8から21までに追加・変更された主要な言語仕様とAPIをまとめたものです。 +バージョン間の差分を理解することで、最新のJavaコードを正しく書き分けることができます。 + +--- + +## Java 8(2014年) +**モダンJavaの基礎となるアップデート** + +- **ラムダ式** + ```java + list.forEach(x -> System.out.println(x)); + ``` + 匿名クラスを簡潔に書ける。 + +- **Stream API** + ```java + list.stream().filter(x -> x > 10).map(x -> x * 2).toList(); + ``` + コレクションを関数的に操作可能。 + +- **Optional** + ```java + Optional.ofNullable(value).orElse("default"); + ``` + Null安全のためのラッパー型。 + +- **Date and Time API (java.time)** + ```java + LocalDate.now(); Instant.now(); + ``` + 新しい日付時刻API(旧java.util.Dateの置換)。 + +- **Defaultメソッド(interface)** + ```java + interface A { + default void log() { System.out.println("log"); } + } + ``` + +--- + +## Java 9(2017年) +**モジュール化とAPI整備** + +- **モジュールシステム(Project Jigsaw)** + ```java + module com.example.app { + requires java.sql; + exports com.example.app; + } + ``` + 大規模プロジェクト向け依存管理。 + +- **try-with-resources改良** + ```java + try (var br = Files.newBufferedReader(path)) { + ... + } + ``` + 既存変数もtryリソースとして扱える。 + +- **Stream API追加メソッド** + `takeWhile`, `dropWhile`, `iterate`(predicate付き) + +- **`var` はまだ導入されていない(Java 10以降)** + +--- + +## Java 10(2018年) +**ローカル変数型推論** + +- **var キーワード** + ```java + var list = new ArrayList(); + ``` + コンパイル時に型を推論。ただしローカル変数限定。 + +--- + +## Java 11(2018年LTS) +**安定版LTS・実用性の向上** + +- **新HTTPクライアント(java.net.http)** + ```java + HttpClient.newHttpClient() + .send(HttpRequest.newBuilder(URI.create("https://example.com")).build(), + HttpResponse.BodyHandlers.ofString()); + ``` + +- **文字列ユーティリティ** + - `" text ".strip()` + - `"a\nb\n".lines()` + - `"abc".repeat(3)` + +- **ファイル読み書きの簡略化** + ```java + String s = Files.readString(Path.of("a.txt")); + ``` + +- **var in lambda** + ```java + (var x, var y) -> x + y + ``` + +--- + +## Java 12〜15(2019〜2020年) +**構文改善と新機能の試験導入** + +- **switch式(Java 14で正式導入)** + ```java + int num = switch (day) { + case MON, TUE -> 1; + default -> 0; + }; + ``` + +- **テキストブロック(Java 15)** + ```java + String json = """ + { + "id": 1, + "name": "test" + } + """; + ``` + +--- + +## Java 16(2021年) +**record と sealed の前段階** + +- **recordクラス(データ専用クラス)** + ```java + public record Point(int x, int y) {} + Point p = new Point(1, 2); + ``` + +- **Stream.toList()** + Java 8までは `collect(Collectors.toList())` が必要だった。 + +--- + +## Java 17(2021年LTS) +**構造的な制約とパターンマッチング** + +- **sealedクラス** + ```java + public sealed class Shape permits Circle, Square {} + public final class Circle extends Shape {} + ``` + +- **instanceofパターンマッチング** + ```java + if (obj instanceof String s) { + System.out.println(s.length()); + } + ``` + +--- + +## Java 18〜20(2022〜2023年) +**テスト的・プレビュー的な改良** + +- **Simple Web Server** + ```bash + jwebserver -p 8080 + ``` + 簡易HTTPサーバを起動できる。 + +- **Recordパターン(プレビュー)** + ```java + if (p instanceof Point(int x, int y)) { ... } + ``` + +--- + +## Java 21(2023年LTS) +**軽量スレッド(Virtual Thread)とパターンマッチの完成形** + +- **Virtual Thread** + ```java + Thread.startVirtualThread(() -> System.out.println("Hello")); + ``` + 数百万スレッドを軽量に扱える。 + +- **Pattern Matching for switch** + ```java + static String format(Object o) { + return switch (o) { + case Integer i -> "int " + i; + case String s -> "str " + s; + default -> "unknown"; + }; + } + ``` + +- **Record Pattern正式採用** + ```java + record Point(int x, int y) {} + if (obj instanceof Point(int x, int y)) { ... } + ``` + +--- + +## まとめ + +| バージョン | 主な特徴 | +| ---------- | ------------------------------------------- | +| 8 | Lambda, Stream, Optional, 新Date/Time | +| 9 | Module System | +| 10 | var(型推論) | +| 11 | 新HTTP, String/Files改善 | +| 14 | switch式 | +| 15 | テキストブロック | +| 16 | record | +| 17 | sealed, instanceof pattern | +| 21 | virtual thread, pattern matching for switch | + +この流れを理解しておくと、古いコードと新しいコードの混在環境でもスムーズに対応できる。 diff --git a/docs/java_maven.md b/docs/java_maven.md new file mode 100644 index 0000000..314dcbb --- /dev/null +++ b/docs/java_maven.md @@ -0,0 +1,229 @@ +# Mavenとは + +Maven(メイヴン)は、Javaプロジェクトのビルド・依存管理・実行を自動化するツールです。 + +* Node.js の npm +* Python の pip + venv + +## Install + +### Windows + +wingetでインストール + +```sh +# JDK +winget install EclipseAdoptium.Temurin.21.JDK +# Maven +winget install Apache.Maven +# 確認 +java -version +mvn -v +``` + +Chocolatey(管理者 PowerShell)でインストール + +```powershell +choco install temurin21 +choco install maven +``` +永続的に設定(PowerShell管理者) + +```powershell +# JDK のインストール先に応じてパスを調整 +setx JAVA_HOME "C:\Program Files\Eclipse Adoptium\jdk-21" +setx MAVEN_HOME "C:\ProgramData\chocolatey\lib\maven\apache-maven-3.9.9" +setx PATH "%PATH%;%JAVA_HOME%\bin;%MAVEN_HOME%\bin" +``` + +プロジェクト作成・実行 + +```powershell +mvn archetype:generate -DgroupId=com.example -DartifactId=hello-maven ` + -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false +cd hello-maven +mvn -q -DskipTests package +``` + +### Mac + +Homebrewでインストール + +```sh +brew install maven +# 確認 +mvn -v +# 出力例 +# Apache Maven 3.9.9 +# Java version: 21.0.2 +``` + +### Linux + +Debian/Ubuntu + +```sh +sudo apt update +sudo apt install -y temurin-21-jdk maven || sudo apt install -y openjdk-21-jdk maven +java -version +mvn -v +``` + +Fedora/RHEL/CentOS Stream + +```sh +sudo dnf install -y java-21-openjdk java-21-openjdk-devel maven +``` + +### Dockerで実行する場合 + +公式イメージ: maven:3.9-eclipse-temurin-21 + +```sh +mkdir hello-maven && cd hello-maven +docker run --rm -it -v "$PWD":/app -w /app maven:3.9-eclipse-temurin-21 \ + mvn -q archetype:generate -DgroupId=com.example -DartifactId=hello-maven \ + -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false + +cd hello-maven +docker run --rm -it -v "$PWD":/app -w /app maven:3.9-eclipse-temurin-21 mvn -q -DskipTests package +``` + + + +# 生成物: target/*.jar はホスト側にも残る + +## How To Setup + +プロジェクト作成 + +```sh +mvn archetype:generate -DgroupId=com.example -DartifactId=hello-maven \ + -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false +``` + +以下の構築が作成されます + +```txt +hello-maven/ +├─ pom.xml +├─ src/ +│ ├─ main/java/com/example/App.java +│ └─ test/java/com/example/AppTest.java +``` + +| オプション | 意味 | +| -------------------------------------------------- | --------------------------------------------------- | +| `archetype:generate` | | +| `-DgroupId=com.example` | グループID(Javaのパッケージ階層にも使われる) | +| `-DartifactId=hello-maven` | アーティファクトID(生成されるプロジェクト名) | +| `-DarchetypeArtifactId=maven-archetype-quickstart` | 使用するテンプレートの種類(標準の“最小構成”の1つ) | +| `-DinteractiveMode=false` | 対話モードをオフ(すべて自動) | + + + +### 基本的なコマンド + +* `mvn compile` + * ソースをコンパイル(`target/classes`へ) +* `mvn exec:java -Dexec.mainClass="com.example.App"` + * 実行(後述のplugin必要) +* `mvn test` + * テスト実行 +* `mvn package` + * jarファイル作成(`target/hello-maven-1.0-SNAPSHOT.jar`) +* `mvn clean`: + * `target`ディレクトリ削除 + + +直接`mvn exec:java`で動かす場合はpluginが必要です。 + +pom.xml +```xml + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + com.example.App + + + + + + +``` + +直接実行する場合は以下です + +```sh +java -cp target/classes com.example.App +``` + +* `-cp`: はクラスパス指定(classpath) +* `com.example.App`は完全修飾クラス名 +* 拡張子`.class`は書かない + +### パッケージ化する場合 + +1. Jarファイルを作成する +2. Jarから実行する + +```sh +# java -cp target/xxx.jar com.example.App +java -cp target/hello-maven-1.0-SNAPSHOT.jar com.example.App +``` + +Javaは通常、.class(target/classes/)と他のライブラリ(.jar)を別々に管理しています。そのままだと実行時に依存jarが必要です。 + +```sh +java -cp target/classes:~/.m2/repository/gson-2.10.jar com.example.App +``` + +`fat jar`にまとめることにより全部ひとつのjarにパッキングできます。 +maven-assembly-pluginが必要になります + +```xml + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.6.0 + + + + com.example.App + + + + jar-with-dependencies + + + + + package + + single + + + + + + + + +``` + +コマンド + +```sh +mvn clean package +java -jar target/hello-maven-1.0-SNAPSHOT-jar-with-dependencies.jar +``` \ No newline at end of file diff --git a/.gitignore b/hello-maven/.gitignore similarity index 100% rename from .gitignore rename to hello-maven/.gitignore diff --git a/hello-maven/pom.xml b/hello-maven/pom.xml new file mode 100644 index 0000000..2c06853 --- /dev/null +++ b/hello-maven/pom.xml @@ -0,0 +1,32 @@ + + 4.0.0 + com.example + hello-maven + jar + 1.0-SNAPSHOT + hello-maven + http://maven.apache.org + + + junit + junit + 3.8.1 + test + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + com.example.App + + + + + + diff --git a/hello-maven/src/main/java/com/example/App.java b/hello-maven/src/main/java/com/example/App.java new file mode 100644 index 0000000..b6bcb1d --- /dev/null +++ b/hello-maven/src/main/java/com/example/App.java @@ -0,0 +1,13 @@ +package com.example; + +/** + * Hello world! + * + */ +public class App +{ + public static void main( String[] args ) + { + System.out.println( "Hello World!" ); + } +} diff --git a/hello-maven/src/test/java/com/example/AppTest.java b/hello-maven/src/test/java/com/example/AppTest.java new file mode 100644 index 0000000..474710c --- /dev/null +++ b/hello-maven/src/test/java/com/example/AppTest.java @@ -0,0 +1,38 @@ +package com.example; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/hello-maven/target/maven-archiver/pom.properties b/hello-maven/target/maven-archiver/pom.properties new file mode 100644 index 0000000..6dbe275 --- /dev/null +++ b/hello-maven/target/maven-archiver/pom.properties @@ -0,0 +1,3 @@ +artifactId=hello-maven +groupId=com.example +version=1.0-SNAPSHOT diff --git a/hello-maven/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/hello-maven/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..03a7c71 --- /dev/null +++ b/hello-maven/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1 @@ +com/example/App.class diff --git a/hello-maven/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/hello-maven/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..b15e758 --- /dev/null +++ b/hello-maven/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1 @@ +/workspace/hello-maven/src/main/java/com/example/App.java diff --git a/hello-maven/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/hello-maven/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst new file mode 100644 index 0000000..5f400a6 --- /dev/null +++ b/hello-maven/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst @@ -0,0 +1 @@ +com/example/AppTest.class diff --git a/hello-maven/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/hello-maven/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000..adb7769 --- /dev/null +++ b/hello-maven/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst @@ -0,0 +1 @@ +/workspace/hello-maven/src/test/java/com/example/AppTest.java diff --git a/hello-maven/target/surefire-reports/TEST-com.example.AppTest.xml b/hello-maven/target/surefire-reports/TEST-com.example.AppTest.xml new file mode 100644 index 0000000..5edefda --- /dev/null +++ b/hello-maven/target/surefire-reports/TEST-com.example.AppTest.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/hello-maven/target/surefire-reports/com.example.AppTest.txt b/hello-maven/target/surefire-reports/com.example.AppTest.txt new file mode 100644 index 0000000..5c184bb --- /dev/null +++ b/hello-maven/target/surefire-reports/com.example.AppTest.txt @@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: com.example.AppTest +------------------------------------------------------------------------------- +Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.275 s -- in com.example.AppTest diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..9154f4c --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,26 @@ +# ---> Java +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* +