エンターテイメント!!

遊戯王好きのJavaエンジニアのブログ。バーニングソウルを会得する特訓中。

【Java】Java15先取り調査 JEP 375: Pattern Matching for instanceof (Second Preview)

JEP

JEP 375: Pattern Matching for instanceof (Second Preview)

内容

大元であるJEP305との違いがよく分からんかった。。。
第二プレビューみたいな感じに捉えたけど、あってるのかな?
英語は、Google翻訳に一任しているから、あってるか、若干不安がある。。。

suzaku-tec.hatenadiary.jp

追加調査

さすがに、これだけだと中身なさすぎるので、以前調べはしたけど、記載してなかった内容を書いておく

ブロック外でキャストした値を参照できるか?

とりあえず、テストコード
やってることは、オブジェクト型にStringを突っ込んで、それをinstanceofで判定&キャストしている。

public class JEP375 {
  
  public static void main(String[] args) {
    Object obj = "JEP375";
    
    if (obj instanceof String s) {
      // (a)
      System.out.println(s);
    } else {
      // (b)
      System.out.println(s);
    }
  }
}

たぶん、(b)でコンパイルエラーになると思う。
そう思った理由は、参照できちゃ不味い箇所だから。

そして、緊張のコンパイル

$  javac --enable-preview -source 15 JEP375.java 
JEP375.java:11: エラー: シンボルを見つけられません
      System.out.println(s);

恥をさらさずに助かった。。。
やはり、参照範囲は、ifのブロック内のみで、elseは対象外だったね。
この参照範囲になっていることで、安全にアクセスできるというわけですね。

感想

はやく入れて欲しい。
実装しているときに、意外と出くわす問題なので、この記述ができるようになるのは、読む方も実装する方も楽だと思う。
特に、基盤とかFW作っている人は、キャストのために変数作ったりするケースは多いんじゃないかな?

変数追加するだけってのを、軽視している人が意外と多いんだよね。
作る側は、そうだろうけど、読む方は、意図を理解するのに苦戦する。
あったほうが可読性上がるケースもあるから、一概には言えないけど、できることなら、変数はなるべく作らないほうがいい。

リーダブルコードに、なんか書いてあった気がする。
読んでるときにものすごい納得したのだが、どう書いてあったのか思い出せない。。。
たまに、読み返してみようかな?

suzaku-tec.hatenadiary.jp

【Java】Java15先取り調査 JEP 360: Sealed Classes (Preview)

JEP

JEP 360: Sealed Classes (Preview)

内容

簡単に言うと、継承先を限定することができるクラスやインタフェースを作れるらしい。

これができる背景には、目的にそぐわない継承やインタフェースの実装が乱立していた事実があるのかもしれない。※個人の予想です。

コード的には、下記のような記載になる。

sealed class Shape permits Circle, Rectangle, Square { }

目新しい違いは、sealedとpermits。
sealedで、今回の機能を使うことを宣言している。
そして、継承を許可するクラスは、permitsで宣言。
例の内容だと、Circle, Rectangle, Squareが継承を許可されたことになる。

調査

まずは、載ってるサンプルを試す。

sealed class Shape permits Circle, Rectangle, Square { }

class Circle    extends Shape { }
class Rectangle extends Shape { }
class Square    extends Shape { }

javaファイル作ったので、コンパイル
preview版なので、--enable-previewをつける。
※本当はコンパイルしようとしたら指摘されて気づいた。。。

$ javac --enable-preview -source 15 JEP360.java 
JEP360.java:3: エラー: sealed、non-sealedまたはfinal修飾子が必要です
class Circle    extends Shape { }
^
JEP360.java:4: エラー: sealed、non-sealedまたはfinal修飾子が必要です
class Rectangle extends Shape { }
^
JEP360.java:5: エラー: sealed、non-sealedまたはfinal修飾子が必要です
class Square    extends Shape { }

なんか、final句つけないとダメらしい。。。
つまり、1世代しか生き残れない親クラスってわけか。
継承できる先を指定しているので、たしかに、そうだなって、思った。

final句つけて、再コンパイル

sealed class Shape permits Circle, Rectangle, Square { }

final class Circle    extends Shape { }
final class Rectangle extends Shape { }
final class Square    extends Shape { }
$ javac --enable-preview -source 15 JEP360.java 

通った。。。
でも、動作を確認できないから、動作確認ようのクラスを追加しないとダメだね。。。

とりあえず作ったサンプルコード!

sealed class Shape permits Circle, Rectangle, Square { }

final class Circle    extends Shape {
  public int center() {
    return 0;
  }
}
final class Rectangle extends Shape {
  public int length() {
    return 1;
  }
}
final class Square    extends Shape {
  public int side() {
    return 2;
  }
}

public class JEP360 {
  public static void main(String[] args) {
    Shape s = new Circle();
    System.out.println(JEP360.getCenter(s));
  }
  
  public static int getCenter(Shape shape) {
    if (shape instanceof Circle c) {
      return c.center();
    } else if (shape instanceof Rectangle r) {
        return r.length();
    } else if (shape instanceof Square s) {
        return s.side();
    }
    
    return -1;
  }
}

そんでもって実行。
期待値としては、Circleクラスを渡しているので、0が返ってきて欲しい。

$ javac --enable-preview -source 15 JEP360.java 
$ java --enable-preview JEP360
0

ちゃんと返ってきたね。

指定以外のクラスで継承するとどうなるのか?

とりあえずサンプルコード

sealed class Shape permits Circle, Rectangle, Square { }

final class Circle    extends Shape {
  public int center() {
    return 0;
  }
}
final class Rectangle extends Shape {
  public int length() {
    return 1;
  }
}
final class Square    extends Shape {
  public int side() {
    return 2;
  }
}

final class Test extends Shape {
  
}

あらたにTestというクラスを追加した。
このクラスは、Shapeを継承しているけど、Shape側のpermitsには含まれていない。

たぶん、コンパイル時にエラーで弾かれると思う。

$ javac --enable-preview -source 15 JEP360.java 
JEP360.java:19: エラー: クラスはシール・クラスShapeを拡張できません
final class Test extends Shape {
      ^

当たり!!
やっぱり、コンパイル時に弾かれるよね。
正解したから、何かご褒美が欲しい。

permitsに存在しないクラスを指定するとどうなるのか?

とりあえず、サンプルコード

sealed class Shape permits Circle, Rectangle, Square, Unknown { }

final class Circle    extends Shape {
  public int center() {
    return 0;
  }
}
final class Rectangle extends Shape {
  public int length() {
    return 1;
  }
}
final class Square    extends Shape {
  public int side() {
    return 2;
  }
}

Unknown が存在しないクラス。
その他は定義済み。

期待値としては、そのままビルド通っていいのでは?って思ってる。

$ javac --enable-preview -source 15 JEP360.java 
JEP360.java:1: エラー: シンボルを見つけられません
sealed class Shape permits Circle, Rectangle, Square, Unknown { }
                                                      ^
  シンボル: クラス Unknown
JEP360.java:1: エラー: 無効なpermits句
sealed class Shape permits Circle, Rectangle, Square, Unknown { }
                           ^
  (スーパータイプUnknownへの参照が不正です)

なんだと。。。
ビルド時にクラスの存在も確認しているのか。。。

感想

クラスをグルーピングできるようになるって理解でよいだろうか?
使う側で不用意な拡張とかされないようになるから、FW側を安全に使うようになる理解でいるが、どうだろう?

若干、疑問に思っているのは、オープン・クローズドの原則と相反する気がするのだが、気のせいだろうか?
なぜ入ったのか、経緯をよく理解できてないせいか、どうにも腑に落ちない。

今年はイベントがほとんどないから、理解があっているのか確かめる場が無いのが痛い。。。

【Java】Java15先取り調査 JEP一覧と概要

一覧

  • 339: Edwards-Curve Digital Signature Algorithm (EdDSA)
  • 360: Sealed Classes (Preview)
  • 371: Hidden Classes
  • 372: Remove the Nashorn JavaScript Engine
  • 373: Reimplement the Legacy DatagramSocket API
  • 374: Disable and Deprecate Biased Locking
  • 375: Pattern Matching for instanceof (Second Preview)
  • 377: ZGC: A Scalable Low-Latency Garbage Collector
  • 378: Text Blocks
  • 379: Shenandoah: A Low-Pause-Time Garbage Collector
  • 381: Remove the Solaris and SPARC Ports
  • 383: Foreign-Memory Access API (Second Incubator)
  • 384: Records (Second Preview)
  • 385: Deprecate RMI Activation for Removal

結構多いな。。。

各JEPのサマリ翻訳

Google翻訳先生、出番です!

339: Edwards-Curve Digital Signature Algorithm (EdDSA)

RFC-8032に記載されている、エドワーズ曲線デジタル署名アルゴリズムを使用した暗号化署名を実装する。

JEP 339: Edwards-Curve Digital Signature Algorithm (EdDSA)

参考リンク

RFC-8032について、分かりやすそうな翻訳サイトがあったのでリンク貼っておく。 RFC翻訳: Edwards-Curve Digital Signature Algorithm (EdDSA) - MOXBOX

雑記

一瞬、ハガレン?って思ってしまいました。
よく考えたら、エドワードの綴って、Edwardだから、sが多いね。。。

360: Sealed Classes (Preview)

密着したクラスとインタフェースをJava言語に提供する。
密着したクラスとインタフェースは、拡張や実装を他クラスに制限することができる。

JEP 360: Sealed Classes (Preview)

雑記

つまり、どういうことだってばよ?
あとで、詳しく調査

371: Hidden Classes

他のクラスのバイトコードから直接使用できないクラスである隠しクラスを導入します。 非表示のクラスは、実行時にクラスを生成し、リフレクションを介してそれらを間接的に使用するフレームワークによる使用を目的としています。 隠しクラスは、アクセス制御ネストのメンバーとして定義でき、他のクラスとは無関係にアンロードできます。

JEP 371: Hidden Classes

雑記

翻訳をそのまま貼り付けた。。。
なんとなくだが、通常ではアクセスできないクラス昨日を提供するみたいだね。
Privateな内部クラスとは、違ったやつなのかな?
どういうシーンで必要になるのか、まだ理解できてない。

372: Remove the Nashorn JavaScript Engine

Nashorn のJavaScriptエンジン、API、jjsツールを削除する。
これらは、Java11でアナウンスしているので削除する。

JEP 372: Remove the Nashorn JavaScript Engine

雑記

さすがに、これはタイトルだけで分かった。

373: Reimplement the Legacy DatagramSocket API

java.net.DatagramSocket、java.net.MulticastSocket APIの実装を、保守およびデバッグが容易で、よりシンプルでより最新の実装に置き換える。 新しい実装は、現在Project Loomで検討されている仮想スレッドでの作業に簡単にさせる。
レガシーソケットAPIをすでに再実装したJEP 353の続きです。

JEP 373: Reimplement the Legacy DatagramSocket API

雑記

内部の動きだけ変える感じかな?
外部の振る舞いは変えないだろうから、使う側としては概要だけ知ってれば良さそう。

374: Disable and Deprecate Biased Locking

デフォルトのバイアスロックを無効にし、関連するすべてのコマンドラインオプションを廃止します。

JEP 374: Disable and Deprecate Biased Locking

雑記

javaコマンドのオプションかな?
あんまり、コマンド叩いたりしないから、ここらへんの知識は疎い。。。

375: Pattern Matching for instanceof (Second Preview)

instanceof演算子のパターンマッチングで、Javaプログラミング言語を拡張する。
プログラム内の一般的なロジックである条件付き抽出をより簡潔かつ安全に表現できる。
これは、JDK 15のプレビュー言語機能です。

JEP 375: Pattern Matching for instanceof (Second Preview)

雑記

来たな、パターンマッチの対応が。
プレビューだけど、適用されれば使えると思うので、早めにキャッチアップしておきたい。

377: ZGC: A Scalable Low-Latency Garbage Collector

Z Garbage Collectorを試験的な機能から製品の機能に変更します。

JEP 377: ZGC: A Scalable Low-Latency Garbage Collector (Production)

雑記

たしか、オラクルが開発したGCだっけ?
停止時間をかなり短くしたような話を聞いたような気がする。

378: Text Blocks

Java言語にテキストブロックを追加します。 テキストブロックは複数行の文字列リテラルであり、ほとんどのエスケープシーケンスの必要性を回避し、予測可能な方法で文字列を自動的にフォーマットし、必要に応じて開発者がフォーマットを制御できるようにします。

JEP 378: Text Blocks

雑記

ここら辺は、予習済みだから、サマリだけで内容は分かる。 過去調べたリンクを貼っておく

suzaku-tec.hatenadiary.jp

suzaku-tec.hatenadiary.jp

利用用途は、たぶん、SQLのベタ書きが多いんじゃないかと思う。
あとは、テンプレート的なものを作りたいとか。

379: Shenandoah: A Low-Pause-Time Garbage Collector

Shenandoahガベージコレクターを実験的な機能から製品の機能に変更します。

JEP 379: Shenandoah: A Low-Pause-Time Garbage Collector (Production)

雑記

何か聞いた気がするのだが、どんなやつだったか忘れた。
GC周りは、あんまり気にしたことがないから、頭に入ってこないんだよね。。。

381: Remove the Solaris and SPARC Ports

ソースコードを削除し、Solaris / SPARCSolaris / x64、およびLinux / SPARCポートのサポートを構築します。 これらのポートは、将来のリリースで削除することを明確に意図して、JDK 14で非推奨になりました。

JEP 381: Remove the Solaris and SPARC Ports

雑記

たしかに非推奨になったのは見た気がする。
当時は、使ってなかったので、ふ~ん程度に考えていた。
今回、deplicateになったやつが削除されるjepが多いな。

383: Foreign-Memory Access API (Second Incubator)

JavaプログラムがJavaヒープ外の外部メモリに安全かつ効率的にアクセスできるようにするAPIを導入します。

JEP 383: Foreign-Memory Access API (Second Incubator)

雑記

概要だけだとよく分からんな。。。
あんまり、メモリを気にしない種族にとっては、スルーしちゃう内容かも。

384: Records (Second Preview)

不変データの透過的なキャリアとして機能するクラスであるレコードを使用して、Javaプログラミング言語を拡張します。 レコードは、名目上のタプルと考えることができます。

JEP 384: Records (Second Preview)

雑記

first previewのときに調べたな。
継続して調べるつもり

suzaku-tec.hatenadiary.jp

385: Deprecate RMI Activation for Removal

今後の削除のためにRMIアクティベーションカニズムを非推奨にします。 RMIアクティベーションは、Java 8以降オプションであったRMIの廃止された部分です。RMIの他の部分は廃止されません。

JEP 385: Deprecate RMI Activation for Removal

雑記

RMIアクティベーションなんて、存在すら知らなかった恥男がここに居ます。

全体通して

deprecateになったやつが、なんやかんやで残るのが常だったけど、ちゃんと削除されるんだな。
計画的にdeprecateを排除する必要があり、最新バージョンを使わなくても内容は追わないとダメだね。

deprecateの綴りを記事途中で間違えている気がしないでもない。

開発者としてキャッチアップしておかないといけないのは、JEP360, JEP375, JEP378, JEP384あたりだろうか?
今回リリースされるJEPが、かなり多い気がする。

【Java】Java15先取り調査 環境構築編

検証環境

Visual Studio Codeのバージョン情報そのまま貼り付け。
たぶん、情報としては足りているはず。

バージョン: 1.48.2 (system setup)
コミット: a0479759d6e9ea56afa657e454193f72aef85bd0
日付: 2020-08-25T10:13:11.295Z
Electron: 7.3.2
Chrome: 78.0.3904.130
Node.js: 12.8.1
V8: 7.8.279.23-electron.0
OS: Windows_NT x64 10.0.18362

環境構築

sdkmanがインストール済みで話を進める。
sdkmanのインストールやら使い方は、過去の記事参照

suzaku-tec.hatenadiary.jp

Java15のインストール

まずは、インストールするバージョン情報を確認する。

$ sdk list java

すると、Java15として下記の情報が出てきた。

 Java.net      |     | 16.ea.13     | open    |            | 16.ea.13-open
               |     | 15.ea.36     | open    |            | 15.ea.36-open
               | >>> | 14.ea.36     | open    | local only | 14.ea.36-open
               |     | 14.ea.24     | open    | local only | 14.ea.24-open
               |     | 14.0.2       | open    |            | 14.0.2-open
               |     | 13.0.2       | open    |            | 13.0.2-open
               |     | 12.0.2       | open    |            | 12.0.2-open
               |     | 11.0.8       | open    |            | 11.0.8-open

もう、Java16のeary build公開されてるんだ。。。
今、欲しいのは、Java15なので、下記のコマンドで15.ea.36をインストール。

sdk install java 15.ea.36-open

少し時間を置くと、下記のようにインストールしたやつをデフォルトにするか聞かれる。

Do you want java 15.ea.36-open to be set as default? (Y/n):

これ、Yを押したはずなんだが、Javaのバージョン確認しても変更されてない。。。
理由を探ってもいいけど、面倒くさいので、下記のコマンドで、Javaのバージョン変更する。

$ sdk use java 15.ea.36

念のため、バージョン確認。

$ java -version
openjdk version "15" 2020-09-15
OpenJDK Runtime Environment (build 15+36-1562)
OpenJDK 64-Bit Server VM (build 15+36-1562, mixed mode, sharing)

$ javac -version
javac 15

ちゃんと変わってるね!
環境構築は、細かく状況を確認していかないと、ズレが発生したときに原因が特定しづらいから、気をつけるようにしてる。

以上、環境構築は終了。

2020/07/27週 気づきと振り返り 熱中症で倒れる前に在宅勤務

業務こなしての問題・気づき

Java

継承の多用

何重にも継承しているクラスを見た。。。

継承の多用は、制約まみれになりそうだなって感じた。
継承先をたどっていくと、継承元で必要ない変数がどんどん出てきて、目を覆いたくなった。。。
また、変数が多いせいで、どこで何をしているのか、よく分からないって感じだった。。。

初期のアーキテクチャ構想が、ものすごく重要だってことを、見てて感じた。

メソッドの結果が戻りにない

メソッドの出力結果が、ローカル変数に入っている。。。
メソッドがクラスに強依存しているのが、処理を追ううえで、辛すぎる。。。

どこで何が設定されるのか分からないのが辛たん。。。

その他雑記

在宅勤務サイコー

出社がないのが最高!
マスク着用してないと、ガチで責められる現場だった。
マスクつけて出社は、熱中症で死にそうだった。
それがなくなるのは、かなり楽。
マスクつけて出社してたころは、午前中、かなり辛かったから、逆に効率は悪かったと思う。

暑さが無くなるまでは、在宅勤務したい。

メガネが・・・

メガネがメガネケースにない。。。
たまにやってしまう。
ケースだけ持ってきて、メガネを忘れるという罠を。

いまは、予備のメガネを常備しているから、業務に支障はでないけど、昔、眼鏡がなくて、ガチで効率が悪かったことがあった。

メガネって、忘れるのが痛い。
コンタクトの人は、つけ忘れることがあるのだろうか?

2020/07/27週 気づきと振り返り みんなマスクをつけて夏を乗り越えるつもりなの?正気??

業務こなしての問題・気づき

1ベンダーに固執するとどうなるか?

DBもIDEもVCSも、同じベンダーの現場であることに気づいた。
たぶん、サポート費用を考慮して1ベンダーにしているのだろうが、明らかに使いにくいのがある。 サポート費用を安く抑えるために、生産性を落としている気がする。。。

選定する側は、どう考えているのだろうか?

個人的には、適材適所でソフトウェアを選んだほうがいいと思う。
1ベンダーが使いやすいものを全て提供しているってのは、無理だと思うんだよね。。。
そんなことができるベンダーがいるのなら、GAFAを駆逐してるだろうって思う。

フォルダ名に半角カナと全角文字が混在

見にくい!!
いや、醜い!!

パット見、半角カナが変な文字に見える。
漢字は、当然、全角なわけで、そこに半角カナが入ると別な言語に見えてしまう。

なんで、こんなに脳に負荷がかかるんだろうな。。。
誰か研究しているやついないかな?

フォルダ移動している最中に、半角カナが目に入ると、メンタルが削られていくような気がする。

マジックナンバーマジックナンバーのままなのだが。。。

現場のソースを見ていて、マジックナンバーマジックナンバーのままの変数を見て、愕然とした。。。

1→ICHI  
NI→2

みたいな。。。。

せっかく名前をつけるのだから、意味を持たせて欲しい。
子どもの名前に、「ぉいだふぇい」みたいな名前にしないだろう。

その他雑記

3連休で急に夏みたいになってきたな。。。
もう、マスクつけるのがシンドい。。。
今の現場、マスクつけてないと怒られるから、キツイ。。。。

朝の出勤で、かなりハードなトレーニングをしている気がする。。。
15分・徒歩+10分・自転車だからね。。。。
夏が終われば、痩せてると思いたい。

出勤すると、だいたい休憩室で涼んでる。
朝ギリギリに来たら休憩できないから、早く来るんだが、みんなギリギリに来ても大丈夫なのか?
それとも、僕の体力が無さ過ぎるのか?

そういえば、ハンディ扇風機?を持っている人を通勤中に必ず見かけるのだが、流行ってるのか?
ダサい上に、デブアピールに見えてしまうのは、私だけでしょうか。。。?

もう、マスクつけるの辞めませんか???
正直、この暑さでマスクつけてると、逆に熱中症で倒れそうな気がするのだが、大丈夫かな?
呼吸しづらい上に、熱がこもるから、熱中症のリスクが高い気がする。
こういうこと言ってると、涼しいマスクとか作られそうで嫌だ。。。

npxを使おうとしてハマった件について

きっかけ

npxって初めて知って、いろいろ調べたりして紆余曲折をまとめる。

環境

vscodeのバージョン情報より。

バージョン: 1.47.3 (system setup)
コミット: 91899dcef7b8110878ea59626991a18c8a6a1b3e
日付: 2020-07-23T13:12:49.994Z
Electron: 7.3.2
Chrome: 78.0.3904.130
Node.js: 12.8.1
V8: 7.8.279.23-electron.0
OS: Windows_NT x64 10.0.18362

npmのバージョンが見えないので、下記だった。

$ npm -v
6.14.5

npxとは

Node.jsに付属するパッケージマネージャー。
ローカルにインストールしたnpmパッケージを、npxコマンドだけで実行できる。

例えば、typescriptでtsconfigを作りたい場合、以下のようにできる。

npx tsc --init

今まで、インストールしたtypescriptのモジュールを指定してやっていることが多かったと思うが、それを簡単に行えるようになるのが利点だと思う。

事件は起きた。。。

いざ、npxでtsconfigやろうとしたら、bash: npx: command not foundが。。。
Node.jsに付属してくるんじゃないの??って疑問符ばかりついて、コマンドをうち間違えてないか、Node.jsがインストールされているか、何回も確認したが、問題なかった。

もう、問題は忘れて、Switchの電源をいれてポケモンをやり始めて、手を付けた日は終わってしまいましたとさ。。。

解決方法

Nodist でインストールした場合、どうやらnpxは含まれないらしい。。。
こういうところがあるから、windowsでの開発が敬遠されがちなのだろうって思ってしまう。

インストールは、下記の方法でOK

npm install npx -g

ローカルにインストール必要性を感じないので、グローバル環境に入れる。

そうすると、ちゃんと使えるようになる。
下記の方法で確認できる。

$ npx -v
10.2.2

参考サイト

Nodist を入れたら npx が使えなくなったので手動でインストール / Twin Turbo Computing

npm 5.2.0の新機能! 「npx」でローカルパッケージを手軽に実行しよう - Qiita

雑記

1日無駄に過ごしてしまったな。。。
やっと何かやる意欲が出たのに、やめるきっかけができてしまうと、簡単に辞めてしまうダメエンジニアでごめんなさい。。。