モチベ
LTSなので、要調査だと感じている。
そこまでやる気はでなかったけど、なんとか調べた。
公式サイト
環境準備
sdkmanを使って環境準備。
環境準備方法は、過去記事を参照
実際に叩くコマンドは、以下の通り。
sdk install 21.ea.35-open sdk use java 21.ea.35-open
実験
JEP430
なんか文字列をフォーマットするの、Javaだと面倒だよねてきなことを言っていて、それをなんとかするための提案らしい。
とりあえず、サンプル動かしてみた。
記載されているコードだと、classとかimport見えないので、追記してコンパイル通るようにしておいた。
ちなみに、FormatProcessorのコンストラクタは、privateで隠蔽されているから、createに変えてある。
import java.util.*; public class Jep430 { public static void main(String[] args) { Locale thaiLocale = Locale.forLanguageTag("th-TH-u-nu-thai"); FormatProcessor THAI = FormatProcessor.create(thaiLocale); for (int i = 1; i <= 10000; i *= 10) { String s = THAI."This answer is %5d\{i}"; System.out.println(s); } } }
実行は、以下の通り
$ javac --enable-preview --release 21 Jep430.java $ java --enable-preview Jep430 This answer is ? This answer is ?? This answer is ??? This answer is ???? This answer is ?????
何やっているかは、よみとけんかった。。。
何かのフォーマットかけているのは分かった。
JEP431
基本データ型について、新規にインタフェースが追加されたっぽい。
とりあえず、公式が載せてるクラス図の画像を載せておく。
今まで各要素へのアクセスするやり方は、以下だったはず。
First element | Last element | |
---|---|---|
List | list.get(0) | list.get(list.size() - 1) |
Deque | deque.getFirst() | deque.getLast() |
SortedSet | sortedSet.first() | sortedSet.last() |
追加されたインタフェースで、もう少しシンプルにできるようになった。
追加されたものを試す。
import java.util.ArrayList; import java.util.Arrays; public class Jep431 { public static void main(String[] args) { ArrayList<Integer> arrayList = new ArrayList<>(); arrayList.add(1); arrayList.add(2); arrayList.add(3); arrayList.add(4); arrayList.add(5); arrayList.addFirst(Integer.valueOf(0)); arrayList.addLast(Integer.valueOf(6)); System.out.println("getFirst:" + arrayList.getFirst()); System.out.println("getLast:" + arrayList.getLast()); System.out.println(arrayList); System.out.println(" --- reversed ---"); System.out.println(arrayList.reversed()); System.out.println(" --- remove ---"); arrayList.removeFirst(); arrayList.removeLast(); System.out.println(arrayList); } }
実行結果は、以下の通り。
$ java --enable-preview Jep431 getFirst:0 getLast:6 [0, 1, 2, 3, 4, 5, 6] --- reversed --- [6, 5, 4, 3, 2, 1, 0] --- remove --- [1, 2, 3, 4, 5]
正常に動いてそう。
Listだけだけど、追加されたインタフェースのやつは動いてる。
ただ、Arrays.asListで生成したやつは動かないので注意
JEP440
以前調べたrecordの最終リリース
一時的な入れ物を作るのなら、なんとかなるはず。
JEP441
switch式でパターンマッチングを利用できるようになった。
ただ、switchアンチ民で、使うケースが想像できなんだよな。。。
とりあえず、サンプルコードをもとにサンプル実装してみた。
import java.util.Arrays; public class Jep441 { public static void main(String[] args) { System.out.println(formatterPatternSwitch(1)); System.out.println(formatterPatternSwitch(1L)); System.out.println(formatterPatternSwitch(1.1)); System.out.println(formatterPatternSwitch("test")); System.out.println(formatterPatternSwitch(Arrays.asList("a", "b", "c"))); } static String formatterPatternSwitch(Object obj) { return switch (obj) { case Integer i -> String.format("int %d", i); case Long l -> String.format("long %d", l); case Double d -> String.format("double %f", d); case String s -> String.format("String %s", s); default -> obj.toString(); }; } }
JEP 452
サンプルをもとに、試し実装。
import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PublicKey; import java.util.Arrays; import javax.crypto.SecretKey; import javax.crypto.KEM; public class Jep452 { public static void main(String[] args) { try { // Receiver side var kpg = KeyPairGenerator.getInstance("X25519"); var kp = kpg.generateKeyPair(); // Sender side var kem1 = KEM.getInstance("DHKEM"); var sender = kem1.newEncapsulator(kp.getPublic()); var encapsulated = sender.encapsulate(); var k1 = encapsulated.key(); System.out.println(k1); // Receiver side var kem2 = KEM.getInstance("DHKEM"); var receiver = kem2.newDecapsulator(kp.getPrivate()); var k2 = receiver.decapsulate(encapsulated.encapsulation()); System.out.println(k2); assert Arrays.equals(k1.getEncoded(), k2.getEncoded()); } catch (Exception e) { // TODO: handle exception } } }
詳細な内容まとめ
ここで、まずキーペアを作成する。
こいつは、すでにある既存のやつなので、説明は省く
// Receiver side var kpg = KeyPairGenerator.getInstance("X25519"); var kp = kpg.generateKeyPair();
鍵交換のアルゴリズムを選定。
生成した公開鍵をもとに、キーを作成する。
// Sender side var kem1 = KEM.getInstance("DHKEM"); var sender = kem1.newEncapsulator(kp.getPublic()); var encapsulated = sender.encapsulate(); var k1 = encapsulated.key();
交換アルゴリズムに秘密鍵をぶちこんで、インスタンスを生成。
生成したインスタンスと交換用のオブジェクトから、キーを生成する。
この生成したキー(k2)が、送信側で生成したキー(k1)と一致するはず。
// Receiver side var kem2 = KEM.getInstance("DHKEM"); var receiver = kem2.newDecapsulator(kp.getPrivate()); var k2 = receiver.decapsulate(encapsulated.encapsulation());
鍵交換を最低限にして、共通キーを交換しているのが利点らしい。
実際の利用方法が想像しにくい。。。
実際に利用すると、処理が分断されて分かりにくくなりそうな気がする。
JEP 453
Concurrency APIを使いやすくするてきなやつらしい。
Concurrency って聞くと、寒気がするので、調べてない。
もう少し、内容が固まったら、調査予定。
初回プレビューだと、情報が少なすぎる。
俺の実力だと調査しきれない。。。
だれか、情報展開をもっとしてくれ(他力本願)
その他雑記+愚痴
JEPに乗ってるコードは、どこまでがサンプルなのか分からなくて、手元で試そうとするとコンパイルエラーになるのが、辛かった。。。
とくにJEP 452がシンドい。
公開鍵の挙動をしらないと、完全に積むだろ、コレ。。。
API読んだり、実装見たりして、コード直しながら毎回試してる気がする。
JEP読むのがハードル高いと思われる原因は、コレでは?って思うの、俺だけ?
サンプルコードがもう少し正確なら、挙動と記載内容から、ある程度理解してもらえると思うんだけどな。。。
英語の壁は、ほとんど感じない。
DeepLで翻訳してるけど、内容はある程度伝わってくるから、技術の進歩はすげぇなぁと思いました(小並感)
どっちかというと、コードの方だよ、問題は。
最初にも書いたけど、書いてあることを見て、コード書くと、コンパイルエラーになるのが、マジで辛たん。。。