※当サイトの記事には、広告・プロモーションが含まれます。

ChatGPTにJava 8(LTS)とJava 25(LTS)のコーディングの比較をお願いしてみた

scienceportal.jst.go.jp

 国連環境計画(UNEP)は11月4日、2024年の世界の温室効果ガス排出量が前年より2.3%増え、二酸化炭素(CO2)換算で過去最多の577億トンに達したとする「目標未達―排出ギャップ報告書2025」を発表した。

温室効果ガスの排出量、過去最多の年間577億トン 「対策強化しないと今世紀中に気温が最大2.8度上昇」とUNEP | Science Portal - 科学技術の最新情報サイト「サイエンスポータル」

地球温暖化対策の国際枠組み「パリ協定」の下で各国が提出した温室効果ガス削減目標(NDC)を達成しても、産業革命前からの気温上昇は今世紀末までに2.3~2.5度、対策を強化しなければ今世紀中に最大2.8度になると指摘。「地球は深刻な気候リスクと損害の拡大に向かっている」と、各国に一層の排出削減策を求めた。

温室効果ガスの排出量、過去最多の年間577億トン 「対策強化しないと今世紀中に気温が最大2.8度上昇」とUNEP | Science Portal - 科学技術の最新情報サイト「サイエンスポータル」

⇧ 気になるのは、過去の「温室効果ガス」の排出量は正確に考慮されているのかということですかね。

過去から合算した場合、欧米とかの「温室効果ガス」の排出量は、相当な量になっているはずですからな...

つまり、「温室効果ガス」の排出量の抑制について、欧米諸国が「債務不履行」な状態になっていないのかはハッキリ可視化してもらわないと困りますと。

 

By the way、先日、

jjug.doorkeeper.jp

⇧ 参加して参りました。

レガシーなコーディングの呪縛が残り続けることによる弊害についてのセッションを聞いて思うのは、非常に根深い問題だなと...

間違った手法が良しとされた状態が続いた時代が長過ぎたので、正しい手法に矯正する労力の負担は想像を絶する...

一応、

scrapbox.io

⇧ 上記サイト様で「問題」の洗い出し、整理はしてくれておりますが、2025年11月16日(日)時点では、「作業中(WIP:Work In Progress)」の状態なので、正しい手法の解決策が未整理ですと。

あと、ちょっと気になったのは、

  1. プリミティブ型
  2. 値オブジェクト

で「パフォーマンス」の影響とか出てこないかということですかね。

膨大なデータを扱う際に、「値オブジェクト」とか「OutofMemory」を引き起こさないのかとかは気になりますな。

JavaのLTS(Long Term Support)

Oracle」が公開しているドキュメントによると、

www.oracle.com

⇧ とあり、2025年11月16日(日)時点での「LTS(Long Term Support)」の最新版は、「Java 25」になりますと。

ChatGPTにJava 8(LTS)とJava 25(LTS)のコーディングの比較をお願いしてみた

奇しくも、2025年に、Java 25 (LTS:Long Term Support)がリリースされたということで、Java 8(LTS:Long Term Support)とJava 25(LTS:Long Term Support)で、どれぐらいコーディングの内容が変わっているのか、「ChatGPT」氏に質問してみたところ、以下のような回答が返ってきた。

1️⃣ モジュールシステム

JEP 261: Module System (Java 9, 2017)

  • 概要Java 9 で導入されたモジュールシステム。アプリケーションをモジュール単位で分割可能。

  • ファイル名:module-info.java

  • import:不要

Java 8 Java 25
// 未対応
java module com.example.app { requires java.net.http; exports com.example.app; }

2️⃣ try-with-resources 強化

JEP 213: Milling Project Coin (Java 9, 2017)

  • 概要:既存変数も try-with-resources に利用可能。

  • ファイル名:TrySample.java

  • import:java.io.*;

Java 8 Java 25
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) { 
  String line = br.readLine(); 
}
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
try (br) { 
  String line = br.readLine();
}

3️⃣ Private interface methods

JEP 213: Milling Project Coin (Java 9, 2017)

  • 概要:インターフェース内に private メソッドを定義可能。

  • ファイル名:Sample.java

  • import:不要

Java 8 Java 25
interface Sample {
  default void run() {
    helper();
  }
}
interface Sample {
  private void helper() {
    System.out.println("help");
  }
  default void run() {
    helper();
  } 
}

4️⃣ Process API 更新

JEP 102: Process API Updates (Java 9, 2017)

  • 概要:プロセス情報の取得・管理が簡単になった。

  • ファイル名:ProcessSample.java

  • import:不要

Java 8 Java 25
Runtime.getRuntime().exec("cmd");
ProcessHandle handle = ProcessHandle.current();
long pid = handle.pid();

5️⃣ System.Logger

JEP 264: Platform Logging API (Java 9, 2017)

  • 概要:標準ロギング API が提供され、軽量かつプラットフォーム依存なしで利用可能。

  • ファイル名:LoggerSample.java

  • import:不要

Java 8 Java 25
// 未対応
System.Logger logger = System.getLogger("app");
logger.log(System.Logger.Level.INFO, "hello");

6️⃣ var(ローカル変数型推論

JEP 286: Local-Variable Type Inference (Java 10, 2018)

  • 概要:ローカル変数宣言で型を省略し var を利用可能。

  • ファイル名:VarSample.java

  • import:java.util.List; java.util.ArrayList;

Java 8 Java 25
List<String> list = new ArrayList<>();
var list = new ArrayList<String>();

7️⃣ HttpClient

JEP 321: HTTP Client (Standard) (Java 11, 2018)

  • 概要:非同期・同期 HTTP リクエストが可能な標準クライアント API

  • ファイル名:HttpSample.java

  • import:java.net.URI; java.net.http.*;

Java 8 Java 25
HttpURLConnection conn = (HttpURLConnection)
new URL(url).openConnection();
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder().uri(URI.create(url)).build();
client.send(req, HttpResponse.BodyHandlers.ofString());

8️⃣ String / Files API 拡張

JEP 330: Launch Single-File Source-Code Programs (Java 11, 2018) / JEP 353: Reimplement Files API for Streams (Java 12, 2019)

  • 概要:Files API や String 読み書きの簡略化。

  • ファイル名:FileSample.java

  • import:java.nio.file.*; java.io.IOException;

Java 8 Java 25
String text = new String(Files.readAllBytes(Path.of("file.txt")));
Files.write(Path.of("file.txt"), text.getBytes());
String text = Files.readString(Path.of("file.txt"));
Files.writeString(Path.of("file.txt"), text);

9️⃣ List.of / Set.of / Map.of

JEP 269: Convenience Factory Methods for Collections (Java 9, 2017)

  • 概要:不変コレクションを簡単に生成可能。

  • ファイル名:CollectionSample.java

  • import:java.util.*;

Java 8 Java 25
List<String> list = Arrays.asList("a","b");
List<String> list = List.of("a","b");

1️⃣0️⃣ switch 式(arrow)

JEP 361: Switch Expressions (Java 14, 2020)

  • 概要:switch が式になり、arrow (->) で簡潔に書ける。

  • ファイル名:SwitchSample.java

  • import:不要

Java 8 Java 25
switch(n) {
  case 1: 
    System.out.println("one");
    break; 
  default: 
    System.out.println("other");
}
String result = switch(n) {
  case 1 -> "one";
  default -> "other";
};

1️⃣1️⃣ Text Blocks

JEP 378: Text Blocks (Java 15, 2020)

  • 概要:複数行文字列を簡潔に記述可能。

  • ファイル名:JsonSample.java

  • import:不要

Java 8 Java 25
String json = "{\n \"a\":1\n}";
String json = """
  { "a": 1 }
""";

1️⃣2️⃣ record

JEP 395: Records (Java 16, 2021)

  • 概要:不変データクラスを簡単に定義可能。

  • ファイル名:User.java

  • import:不要

Java 8 Java 25
class User {
  private String name;
  private int age;
  public User(String n,int a){
    name=n;age=a;
  }
  public String getName(){
    return name;
  }
  public int getAge(){
    return age;
  }
}
public record User(String name,int age) {}

1️⃣3️⃣ pattern matching for instanceof

JEP 394: Pattern Matching for instanceof (Java 16, 2021)

  • 概要:instanceof とキャストを簡略化。

  • ファイル名:PatternSample.java

  • import:不要

Java 8 Java 25
if (obj instanceof String) {
  String s = (String)obj;
}
if (obj instanceof String s) {
   //...
}

1️⃣4️⃣ Stream API 新メソッド

JEP 269: Convenience Factory Methods for Collections / JEP 378: Stream API 拡張 (Java 9〜16, 2017〜2021)

  • 概要dropWhile, takeWhile, toList など Stream API の拡張。

  • ファイル名:StreamSample.java

  • import:java.util.*; java.util.stream.*;

Java 8 Java 25
list.stream()
  .filter(s -> s.length() > 0)
  .collect(Collectors.toList());
list.stream()
  .dropWhile(s -> s.isEmpty())
  .takeWhile(s -> s.length() < 5)
  .toList();

1️⃣5️⃣ sealed class / sealed interface

JEP 409: Sealed Classes (Java 17, 2021)

  • 概要:クラス・インターフェースの継承を限定可能。

  • ファイル名:Shape.java / Circle.java / Square.java

  • import:不要

Java 8 Java 25
abstract class Shape {}
public sealed interface Shape permits Circle, Square {}
public final class Circle implements Shape {}
public final class Square implements Shape {}

1️⃣6️⃣ Virtual Threads

JEP 444: Virtual Threads (Java 21, 2023)

  • 概要:軽量スレッドの導入。従来の OS スレッドより効率的。

  • ファイル名:ThreadSample.java

  • import:不要

Java 8 Java 25
new Thread(() -> doWork())
  .start();
Thread.startVirtualThread(() -> doWork());

1️⃣7️⃣ switch パターンマッチ

JEP 441: Pattern Matching for switch (Java 21, 2023)

  • 概要:switch 式にパターンマッチを統合。

  • ファイル名:SwitchPatternSample.java

  • import:不要

Java 8 Java 25
switch(shape) {
  case Circle: 
    //... 
    break;
  case Square: 
    //...
    break;
  default:
    break;
}
switch(shape) {
  case Circle c -> System.out.println(c.radius());
  case Square s -> System.out.println(s.side());
}

1️⃣8️⃣ Optional 新メソッド

JEP 269: Optional Enhancements (Java 9, 2017)

  • 概要ifPresentOrElse, orElseThrow(), isEmpty(), stream() 追加。

  • ファイル名:OptionalSample.java

  • import:java.util.Optional;

Java 8 Java 25
Optional opt = Optional.of("hello");
if (opt.isPresent()) {
  System.out.println(opt.get());
}
Optional<String> opt = Optional.of("hello");
opt.ifPresentOrElse(System.out::println, () -> System.out.println("empty"));
if (opt.isEmpty()) {
  System.out.println("empty");
}
opt.stream().forEach(System.out::println);

1️⃣9️⃣ Map 新 API

JEP 269: Map Enhancements (Java 9, 2017)

  • 概要putIfAbsent, replaceAll, merge 追加。

  • ファイル名:MapSample.java

  • import:java.util.*;

Java 8 Java 25
Map<String,String> map = new HashMap<>();
map.put("key","value");
map.getOrDefault("key","default");
Map<String,String> map = new HashMap<>();
map.putIfAbsent("key","value");
map.replaceAll((k,v) -> v.toUpperCase());
map.merge("key","new",(oldVal,<) -> oldVal + <);

2️⃣0️⃣ Files.walk Stream / Files API 拡張

JEP 353: Reimplement Files API for Streams (Java 12, 2019)

  • 概要:Stream を try-with-resources で安全に利用可能。

  • ファイル名:FilesSample.java

  • import:java.nio.file.*; java.io.IOException;

Java 8 Java 25
Files.walk(Paths.get("."))
  .forEach(System.out::println);
try (var paths = Files.walk(Path.of("."))) {
  paths.forEach(System.out::println);
}

2️⃣1️⃣ RandomGenerator

JEP 356: Enhanced Pseudo-Random Number Generators (Java 17, 2021)

  • 概要:複数アルゴリズムの PRNG を統一インターフェースで提供。

  • ファイル名:RandomSample.java

  • import:java.util.random.RandomGenerator;

Java 8 Java 25
Random r = new Random();
int n = r.nextInt(100);
RandomGenerator rng = RandomGenerator.of("Xoshiro256PlusPlus");
int n = rng.nextInt(100);

2️⃣2️⃣ String API 拡張

JEP 355: Text Blocks / String Methods (Java 13, 2019)

  • 概要repeat, strip, isBlank, lines 追加。

  • ファイル名:StringSample.java

  • import:不要

Java 8 Java 25
String s = " abc ".trim();
String s = "abc".repeat(3);
String t = " abc ".strip();
boolean empty = " ".isBlank();
s.lines().forEach(System.out::println);

2️⃣3️⃣ Date/Time API 拡張

JEP 378: Date/Time Enhancements (Java 14, 2020)

  • 概要datesUntil, timesUntil で範囲を Stream で取得可能。

  • ファイル名:DateSample.java

  • import:java.time.*;

Java 8 Java 25
LocalDate ld = LocalDate.parse("2023-01-01");
LocalDate ld = LocalDate.parse("2023-01-01");
ld.datesUntil(ld.plusDays(5)).forEach(System.out::println);

2️4️⃣ 簡略化された main メソッド

JEP 430: Structured Concurrency and Simplified Main (Java 21, 2023)

  • 概要public static void main(String[] args) を書かずに、void main() やトップレベルコードだけで main として実行可能になった。

  • ファイル名:Main.java

  • import:不要

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

2️⃣5️⃣ 量子耐性鍵カプセル化(ML-KEM)

JEP 496: Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism

  • 概要:量子耐性のモジュール格子に基づく KEM(ML-KEM)を `KeyPairGenerator`、`KEM`、`KeyFactory` API で提供。 :contentReference[oaicite:0]{index=0}
  • パラメータセット:`ML-KEM-512`、`ML-KEM-768`、`ML-KEM-1024` を `NamedParameterSpec` で指定可能。 :contentReference[oaicite:1]{index=1}
Java 8(量子耐性未対応) Java 25(または Java 24)での ML-KEM 利用例
public class KEMExample {
  public static void main(String[] args) throws Exception {
    // Java 8 には ML-KEM 実装がないので、代わりに標準的な非量子鍵交換を使う例:
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
    kpg.initialize(2048);
    KeyPair kp = kpg.generateKeyPair();
    System.out.println("Public Key: " + kp.getPublic());
    System.out.println("Private Key: " + kp.getPrivate());
  }
}
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.spec.NamedParameterSpec; import javax.crypto.KEM;

public class MLKEMExample {
  public static void main(String[] args) throws Exception {

  // 鍵ペア生成(パラメータセットを指定)
  KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM");
  kpg.initialize(NamedParameterSpec.ML_KEM_512);
  KeyPair kp = kpg.generateKeyPair();

  // カプセル化(送信側)
  KEM kem = KEM.getInstance("ML-KEM");
  KEM.Encapsulator enc = kem.newEncapsulator(kp.getPublic());
  KEM.Encapsulated encapsulated = enc.encapsulate();

  // カプセル化メッセージ(送信)
  byte[] message = encapsulated.encapsulation();

  // 共有鍵
  javax.crypto.SecretKey shared1 = encapsulated.key();

  // 復号(受信側)
  KEM.Decapsulator dec = kem.newDecapsulator(kp.getPrivate());
  javax.crypto.SecretKey shared2 = dec.decapsulate(message);

  // 両者の鍵が一致するはず
  System.out.println("Shared1: " + java.util.Base64.getEncoder().encodeToString(shared1.getEncoded()));
  System.out.println("Shared2: " + java.util.Base64.getEncoder().encodeToString(shared2.getEncoded()));
  }
}

2️⃣6️⃣ 量子耐性署名(ML-DSA)

JEP 497: Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm

  • 概要:量子耐性のモジュール格子に基づく署名アルゴリズム ML-DSA を `KeyPairGenerator`、`Signature`、`KeyFactory` API で提供。 :contentReference[oaicite:2]{index=2}
  • パラメータセット:`ML-DSA-44`、`ML-DSA-65`、`ML-DSA-87` を `NamedParameterSpec` 経由で指定可能。 :contentReference[oaicite:3]{index=3}
Java 8(量子耐性未対応) Java 25(または Java 24)での ML-DSA 利用例
public class SignatureExample { 
  public static void main(String[] args) throws Exception { 
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
    kpg.initialize(2048);
    KeyPair kp = kpg.generateKeyPair();

    Signature sig = Signature.getInstance("SHA256withRSA");
    sig.initSign(kp.getPrivate());
    byte[] message = "Hello, quantum-free world".getBytes();
    sig.update(message);
    byte[] signature = sig.sign();

    System.out.println("Signature: " + java.util.Base64.getEncoder().encodeToString(signature));

    // 検証
    Signature verifier = Signature.getInstance("SHA256withRSA");
    verifier.initVerify(kp.getPublic());
    verifier.update(message);
    boolean ok = verifier.verify(signature);
    System.out.println("Verified: " + ok);
  }
}
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Signature;

public class MLDSAExample {
  public static void main(String[] args) throws Exception {
    // 鍵生成(デフォルトパラメータセットは ML-DSA-65)
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-DSA");
    KeyPair kp = kpg.generateKeyPair();

    // 署名
    Signature signer = Signature.getInstance("ML-DSA");
    signer.initSign(kp.getPrivate());
    byte[] msg = "Hello, quantum-secure world".getBytes();
    signer.update(msg);
    byte[] sigBytes = signer.sign();
    System.out.println("Signature: " + java.util.Base64.getEncoder().encodeToString(sigBytes));

    // 検証
    Signature verifier = Signature.getInstance("ML-DSA");
    verifier.initVerify(kp.getPublic());
    verifier.update(msg);
    boolean valid = verifier.verify(sigBytes);
    System.out.println("Verified: " + valid);
  }
}

 

まぁ、「幻覚(ハルシネーション)」を発生していそうなのだが、流石に、

の比較だと、変更が網羅し切れない感じはあるのと、「後方互換性」とか限界ありそうな感じの変更が結構な数、導入されていそうですね…

マイグレーション作業が大変そうですな...

大きな変化としては、

  • Record クラス
  • Sealed クラス
  • Sealed インターフェース
  • 量子耐性暗号化技術

などの導入ですかね。

 

2025年11月17日(月)追記:↓ ここから

ちなみに、「StringBuilder」の内部的な実装も変遷を辿っているらしく、「ChatGPT」氏に質問してみたところ、以下のような回答が返ってきた。

 

項目 Java 8 以前 Java 9 Java 11 以降(およびモダン JVM
StringBuilder の基本実装 StringBuilderAbstractStringBuilder を継承。内部は char[] value バッファ。 Stack Overflow+2Kengo's blog+2 基本構造は同じ (AbstractStringBuilder + char[])。API仕様にも変更なし。 Oracle Docs 継続して同様。StringBuilder クラス自体の public API に大きな変更はなし。 Oracle Docs
内部バッファの型(文字表現) char[](UTF‑16)を使っている。 Java 9 で導入された Compact Strings の影響を受けた String は内部に byte[] + エンコーディングフラグで保持されるが、AbstractStringBuilder / StringBuilder も同様な表現に更新されている。 openjdk.org+1 同上(Compact Strings + バイト配列表現を利用)。 JEP 254 で StringBuilder もこの新しい内部表現をサポートすることが明記されている。 openjdk.org
文字列連結(+ 演算子)のバイトコード生成 / 実行 javacStringBuilder を使った append チェーンを生成。このため、連結は実行時に StringBuilder を明示的に使っているのと似た形になる。 JEP 280: Indify String Concatenation によって、+ 演算子invokedynamic を使う方式に変わった。 openjdk.org+1
具体的には、StringConcatFactory.makeConcatWithConstants をブートストラップメソッドとして使う。 Guardsquare
継続して上述の invokedynamic ベース結合が使われる。Java 11 などではより最適化が効き、実行時パフォーマンスが向上しているケースが多い。
(例えば、JDK 9 でのベンチマークで StringBuilder を使った結合よりも高速になる例がある) TECHSCORE+1
インタフェース / API の変更 StringBuilderSerializable, Comparable<StringBuilder>, CharSequence を実装。 Oracle Docs 基本的に同じ。 JDK 21 などで、Appendable インタフェースを明示的に StringBuilder が実装するように修正された。 bugs.openjdk.org+1
性能・メモリの違い 典型的なチャンク増加(バッファ再確保)は AbstractStringBuilderexpandCapacity によって行われる。 Kengo's blog Compact Strings の導入により、Latin-1 文字列(例: ASCII文字列)はメモリ使用量が削減される。 openjdk.org
+ 演算子による結合の最適化(invokedynamic 利用)により、一部ケースで高速化。 TECHSCORE+1
モダン JVM の最適化が進んでおり、String.concat/+ 演算子の連結が非常に効率的に動作することが多い。特に JDK 9 以降では従来の StringBuilder チェーンより有利になるケースも。

⇧ 例のごとく「AI」の「幻覚(ハルシネーション)」の問題があるので、真偽が定かではないのだが、

www.sakatakoichi.com

qiita.com

⇧ 上記サイト様で、「文字列連結」での「invokedyamic」について解説してくださっているようです。

2025年11月17日(月)追記:↑ ここまで

 

ちなみに、「Lombok」と「Recordクラス」の比較については、

developer.mamezou-tech.com

⇧ 上記サイト様が詳しいです。

ちなみに、「ChatGPT」氏に「Record」クラスで「プライベート コンストラクタ」が実現できないか質問してみたところ、以下のような回答が返ってきた。

 

結論から言うと:

Record に「完全な private コンストラクタ」を付けることは、どんなデザインパターンを使っても“仕様上”不可能です。 ただし「Record を new されないように誘導する」デザインパターンは実現できます。

理由と、「代替案としてできること」をデザインパターンの観点で整理します。

❌ なぜデザインパターンでも private コンストラクタ化は不可能なのか

Java 言語仕様(JLS)では:

  • Record の canonical constructor(正規コンストラクタ)は必ず public

  • アクセス修飾子を変えることは 禁止

とされています。

つまり、

Factory Method / Builder / Singleton / Abstract Factory

などで“private コンストラクタを隠したインスタンス生成”を実現しようとしても、

そもそも Record が private にできないので成立しません。

 

できることと、できないことのまとめ

やりたいこと Record でできる? デザインパターンで補える? 説明
Record の new を完全に禁止 言語仕様で不可能
new されにくい API の提供 Factory Method で実現
値検証を一元化 Factory Method + コンパクトコンストラク
Record を直接使わせずラップ Adapter / Decorator
ドメインロジックを閉じ込める 値オブジェクトパターン

 

🎯 結論(実務指針)

Record は「private コンストラクタが必要な領域(独自の生成制御)」には向かない。 そうしたい場合は通常の class を使うべき。

しかし Record を使いながら生成を“誘導”するために:

  • Factory Method

  • Wrapper(Adapter / Decorator)

  • 値オブジェクトパターン

を併用すると実務的には十分安全な設計ができる。

 

とのこと。

う~む...、「Record」クラスは、何故、中途半端な仕様になっているのか謎過ぎるのだが...

ちなみに、「Sealed」クラスやインターフェースも、対象が増える度に「permits」に追加変更が発生するので微妙なのよな...

例えば、「Ruby」のライブラリ「Oxidized」というものがあるのだが、

github.com

⇧ サポートしている「ネットワーク機器」が130種類オーバーらしいのだが、ベンダーの数も相当な数あると思うので、仮に「Java」で「Sealed」インターフェースとか使って実装するとなると、「permits」への追加変更の地獄が始まるのよな...

数が滅多に変動しないような、

  1. 会員の種類
  2. カードのランク
  3. 体重別階級
  4. 図書分類法
  5. 品質レベル
  6. 危険度・カテゴリー
  7. 感染症危険情報
  8. バイオセーフティーレベル(biosafety level, BSL)
  9. IUCN(※1)レッドリストカテゴリー
  10. デオキシリボ核酸(deoxyribonucleic acid、DNA)
  11. 人種
  12. etc...

※1 国際自然保護連合。International Union for Conservation of Nature and Natural Resources。

などで利用しないと効果が薄いってことなのかね...

いまいち、「Java」の設計思想が謎なのよな...

何と言うか、「リリース」サイクルを無理に早めなくて良いから、もう少し、「仕様」をしっかりと整理して欲しい気はする。

毎度モヤモヤ感が半端ない…

今回はこのへんで。