2022/11/15

JavaOne 2022に行ってきました

このエントリーをはてなブックマークに追加
_DSC7423
10月18日から3日間にわたって開催されたJavaOne 2022に参加してきました。
今年は久しぶりにJavaOneという名前が復活し、ラスベガスでの初めての開催ということになりました。

技術的なことはさておき、初のラスベガス開催ということで、来年参加する人たちの参考になればということで備忘録を書いておきます。

現地まで

残念ながら日本からラスベガスまでの直行便はありません。日本からだと以下の3つが主な乗り継ぎ空港ですね。
  • ロスアンゼルス
  • サンフランシスコ
  • シアトル
今回は知り合いの日本人参加者ではロス乗り継ぎが多かったです。私はサンフランシスコで乗り継ぎました。

飛行機代を抑えたいのであれば、LCCのZipairがロスアンゼルスやサンノゼまで飛んでいるので、それを利用するというのもありかもしれません。

アメリカ入国

どの空港で乗り継いだとしても入国審査は乗り継ぎの空港、私の場合はサンフランシスコ空港で行います。

アメリカに入国するにはESTAが必要です。ESTAは2年間有効で、ESTAを申請したはじめての時は有人の入国審査になりますが、その後は自動入国審査端末での審査になります。

今年はコロナになってから久々のアメリカだったので、ESTA申請し、審査官による入国審査でした。アメリカの入国審査官ってなんであんなにいろいろ聞いてくるんでしょうね😰

そして、来年はどうなるか分からないですが、今年はコロナに関する宣誓書を書いておく必要がありました。また、コロナワクチンの接種証明はいつでも見せられるようにしておきました。実際には見せる機会はありませんでしたが、念のため。

接種証明はマイナンバーカードを持っている人であれば、スマホの接種証明書アプリが便利です。マイナンバーカードを持っていない場合は、役所で英語表記の接種証明書を入手します。

ラスベガスまで

入国した空港から、ラスベガスのハリーリード国際空港(以前はマッカラン国際空港でしたが去年名称が変わりました)までは国内線で乗り継ぎます。

ハリーリード空港はターミナル1と3があります。私はUnited Airlinesだったのでターミナル3でした。

ハリーリード空港はいたるところにスロットマシンが置いてあって、さすがカジノの街という感じです。

ターミナル3はゲートがある建物と荷物カウンター(Baggage Claim)がある建物が別々になっていて、トラムで結ばれています。ただ、トラムが荷物カウンターに向かうものと、ターミナル1に向かうものの2種類あるので間違わないようにしないといけません。

大きい階段があって、Welcome to Las Vegasと書いてある看板?を下っていった先にあるのが、荷物カウンター行きのトラムです。

荷物を受け取ったら街に向かいましょう。
_DSC0834

ホテルまで

ハリーリード空港は市街地まではUberやLyftなどのライドシェア、タクシー、バスなどの選択肢があります。

タクシーの場合、空港から市街地は定額で$27だそうです。これに空港使用料とチップが加わります。

ライドシェアは混雑する時間帯はタクシーとあまり変わらない値段ですが、混雑していない場合はチップも含めても$20ぐらいです。

ライドシェアはどこでも呼べるわけではなく、空港内の決められた場所でしか乗車できないようになっています。

ターミナル3の場合、乗車できるのはパーキングの建物の中にあります。

荷物カウンターの階(Level 0)から1つあがって、49番の出口を出るとパーキングに向かう橋があります。パーキングについたら、1つ下の階(Level V)にライドシェアの乗車場があります。

乗車場についたらUberやLyftのアプリを使って、行き先と車の種類を指定して、配車できます。

ホテル

ラスベガスは南北に走るストリップを中心に街が構成されています。ストリップでも中心に なるのがフォーコーナー (Four Corners)と呼ばれる交差点です。

おおざっぱにいうとフォーコーナーに近い方がホテルの宿泊費が高く、離れると安くなる傾向があります。特に東西方向はストリップからちょっと離れるだけで急に安くなるようです。

JavaOneの会場はフォーコーナーにほど近いシーザースフォーラムというところです。そこのため、ホテルを選ぶには2つの選択肢があると思います。
  • 会場に近くて便利だが、宿泊費は高いホテル
  • 会場から遠いが、宿泊費は安いホテル
宿泊費は高いといっても、今までのサンフランシスコに比べればかなり安いです。

私は今回、会場に近いフラミンゴ(Flamingo)に宿泊しました。フラミンゴは古いホテルなので設備とかはかなりイマイチな感じ。古いホテルのためか、フォーコーナー近くのホテルの中では比較的安いです。

会場に近いので、ノベルティもらって荷物が多くなった時など、部屋に戻って荷物を置いてくるなんてことができるのは便利です。

フラミンゴやベネチアン(The Venetian)などは、JavaOne登録と一緒にホテルの予約もできるので、それを利用するというのも1つの手です。カンファレンスレートで、通常よりは少しだけ安くなっているはずです。

気候

ラスベガスは砂漠の中にあります。10月でしたが、最高気温は30度ぐらい。最低気温が15度ぐらいで、朝晩は過ごしやすいです。乾燥しているので、昼でも直射日光に当たらなければ、意外に過ごしやすかったです。

気になるのが会場の冷房だったのですが、意外にもそんなに冷えてはいませんでした。それでも、1枚羽織るものがあるといいと思います。

治安

最近、アメリカ各地で治安が悪くなったと聞きますが、ラスベガスのストリップ近辺は特に治安が悪い感じは受けませんでした。

ストリップからちょっと離れたところには治安の悪いところもあるらしいですが、そこまで行くことはないでしょうから、治安について心配することはないようです。

もちろん、ホームレスはいますが、お金をせびってくるようなホームレスには遭遇しませんでした。とはいっても、日本の感覚でいるのは危険なので、注意は必要です。

SIM

今まで海外旅行に行くときには、プリペイドSIMを普段使っているSIMと入れ替えて使っていました。

今回はじめてeSIMを使用しました。日本でプリペイドのeSIMを購入して、事前に設定しておきました。後はアメリカについたら、eSIMを有効化すればいいだけなので、とても楽。

プリペイドeSIMもいくつか選択肢がありますが、今回はソラコムのグローバルeSIMを使用しました。ソラコムのeSIMはデータ通信だけなのですが、通話はしないので全然OKです。

プリペイドeSIMを提供している企業によっては通話もできるところがあるようなので、必要であれば探してみるのもいいかもしれません。

なお、会場やホテルではWi-Fiが使えます。今回、会場のWi-Fiが瞬断することがありましたが、使えない状態が続くとか、遅くて使えないということはありませんでした。

まぁ、今回は参加人数が少なかったからということもあるかもしれません。

会場

今回のJavaOneの会場はCaesars Forumで、CloudWorldはThe Venetian Expoで行われました。両会場は橋でつながっていて行き来できるようになってます。

本来なら、3年前にCaesars Forumのこけら落としがOpenWorld/Code Oneだったんですけど、コロナで延期。まぁ、しかたありません。


Caesarsと名前がついていますが、Caesars Palaceからは離れていて、Harrahsの東側にあります。HarrahsやLINQからは直接Caesars Forumに入ることができ、またFlamingoの北側の道から観覧車のHigh Rollerの真下にCaesars Forumへ入る通路があります。

The Venetian ExpoはCaesars Forumの北側で、The Venetianから直接入ることができるのですが、カジノを通り抜けなくてはいけなくて、これがまた迷路のようになっているので、迷わずにいくのはなかなか大変です。

先述したように、会場はWi-Fiが使えます。また、今回は朝食とランチが提供されて、Caesars Forumの南側のテラス席でも食べることができました。暑くなければ、いい感じなんですけどね。

食事

ラスベガスは観光客向けの飲食店はいたるところにあります。でも、なんかみんな観光客向けの大箱、かつバックに資本がついているところばかりなような気がするんですよね。もちろん、そういう需要があることは分かるのですが、私の嗜好とは合わないのです。

ファストフード

1人でさくっと行きやすいといえば、ファストフードですね。McDonald'sやBurger Kingなどのように日本でも展開しているチェーン店もありますが、せっかくならば日本にない、もしくは日本ではまだそれほど店舗が多くないところを選んでみるのはどうでしょう。

  • In-N-Out Burger
  • Chick-fil-A
  • Chipotle Mexican Grill
  • Panda Express
In-N-Out (イン アンド アウト)はハンバーガーチェーンですが、裏メニューのカスタムがいっぱいあることや、冷凍のポテトを使わないなどで有名なところです。

Caesars Forumからも近いのですが、人気なのでいつも行列してました。とはいうものの、回転は早いので、そんなに待つこともないと思います。

Chick-fil-A (チックフィレイ)はチキンバーガーのチェーン店。KFCのチキンフィレバーガーのような感じです。Chik-fil-Aも人気ありますね。

Chipotoleはブリトーやタコスなどのメキシカンのチェーン店。ファストフードとしては珍しい地産地消をうたっています。日本からのJavaOne参加者にもここのファンという人が多いです。

最後のPanda Expressはアメリカンな中華のチェーンです。名物はオレンジチキン。日本では1度撤退していますが、2016年に再進出してます。でも、まだ店舗はそんなにないので、アメリカで行ってみるのはありだと思います。

フードコート

フードコートも1人で行くにはいいですね。だいたいのカジノにはフードコートがあるようです。

たとえば、Cloud World会場のベネチアンには2つのフードコートがあり、ハンバーガーのJohnny RocketsやFat Burger、上にも書いたPanda Expressなどがあります。

店を探す

やっぱりファストフードはやだという場合には店を探すわけですが、そんな時に役に立つのがアメリカ版食べログとでもいえるYelpです。
だいたいの店が予約可能なので、できることなら予約してから行った方がいいと思います。そんな時に使えるのが、OpenTableです。
日本のトレタやTableCheckのようなものですが、OpenTableの方が古くからあり、店の検索などもずっとやりやすくなっています。

今回もOpenTableで予約をとっていったところが多かったです。ただし、ホテル内にあるレストランはホテルの予約システムを使っていることがあるので、そちらもチェックした方がいいと思います。

とはいうものの、店が多いので、目当ての店があるとかでもないと、なかなか難しいですね。

参考までに今回ラスベガスで行ったレストランを列挙しておきます。

レストラン
  • Bouchon Bistro
    ナパにあるミシュラン三つ星のThe French Laundryの姉妹店のビストロ。本店はナパにあります。ナパのBouchonにも行ったことがありますが、ラスベガスの方がフォーマルな感じですね。とはいっても、ドレスコートがあるわけではなさそうですが。
    ベネチアンの10階にありますが、テラス席まであります。ぜんぜん10階のような感じがしないですが、とても静かでいいですね。
    朝ごはんに行ったのですが、ナパのBouchonはパンがおいしいので、クロワッサン。それとメインのサーモンのグリル。デザートも朝から頼めるというので、プロフィットロール。朝からいい気になって頼んだら、1万円超えてしまいました😰 でも、おいしかったので、OK。
    _DSC5763 _DSC5810 _DSC5875
  • Bardo Brasserie
    ARIAリゾートの中にあるブラッセリー。内装がウッディーで重厚な感じ。
    ここも朝ごはんで開店と同時に入店したのですが、開店待ちの人がいっぱい。このブログを書くために調べてみたら、Michael Mina系列のブラッセリーでした。Michael Minaもスターシェフなので、この人気もわかりますね。
    ここでは、タルタルとフレンチトースト。フレンチトーストはブリオッシュなので、そんなに大きくないだろうと高をくくっていたら、超巨大でした。
    _DSC0704 _DSC0751 _DSC0822
  • Sugarcane Raw Bar Grill
    _DSC6119 _DSC6127 _DSC6160
  • Off the Strip
    _DSC6300
ハンバーガー

WahlburgersもBurger Barもチェーン店ですが、Wahlburgersの方がファストフードに近い感じで、私にはBurger Barの方がよかったです。アメリカでハンバーガー食べると、日本のグルメバーガーがいかにおいしいか分かりますね😂

Wahlburgersでハンバーガーとサラダを食べていたら、隣に座っていたおじいさんにBig Dinnerだねと言われてしまいました🤣 
  • Wahlburgers
    _DSC5704 _DSC5723
  • Burger Bar
    _DSC0528
ステーキ
ステーキは、フレンチやイタリアンなどに比べると、シェフの技量よりも材料に起因する部分が大きいような気がします。つまり、いい肉を使っているかどうか。値段が高いところはいい肉を使っているので、おいしいわけです。もちろん、例外はありますけど。

とはいうものの、2倍の値段だったら、2倍おいしいということはないので、そこらはバランスですね。

2店行きましたが、Gordon Ramsayの方が値段が高いだけあっておいしかったです。Smith & Wollenskyもおいしかったんですけどね。

ちなみに、Gordon Ramsayもスターシェフで、ラスベガスにいろいろなジャンルの店があります。最近、Fish & Chipsの店をオープンしたらしいのですが、いつも行列していたので行くのをあきらめました。来年、行こうっと!
  • Smith & Wollensky
    _DSC6413 _DSC6459
  • Gordon Ramsay Steak
    _DSC7214 _DSC7219 _DSC7260 _DSC7294
スイーツ

アメリカは、おいしいスイーツがなかなかないんですよね。ラスベガスでもそういう感じでした。

たまたま帰国する日が、シザースパレスにドミニクアンセル (Dminique Ansel Bakery)がオープンするということだったので行ってみたのですが、すごい行列。

ドミニクアンセルは以前、表参道にもあったのですが撤退してしまったので、久しぶりに食べられると思ったのですが、さすがに行列に並ぶと飛行機に遅れてしまうので断念。

来年リベンジします。
  • Sweets Raku
    アメリカでアシェットデセールの店があるとは思いませんでした。とはいっても、日本人がオーナーで、パティシエも日本人。どおりで!
    日本人が作っているということで、日本の繊細なデザートが食べられます。ラスベガスでパフェ食べらるのはたぶんここだけ。というか、日本のパフェは日本独自のデザートなので、外国ではなかなか食べられないのです。
    _DSC6075 _DSC5981
  • Dandelion Chocolate
    サンフランシスコに本店があるビーントゥバーチョコレートのDandelion Chocolate。日本にも蔵前に店があります。
    ここはチョコはもちろん、チョコを使ったスイーツもおいしいです。
    ついでですが、ここが使っているコーヒー豆がサードウェーブ系で有名なRitual。ラスベガスでおいしいコーヒーをなかなか見つけられなかったので、チョコを食べなくてもコーヒーを飲みに来るのはありですね。
    _DSC7493 _DSC7508 _DSC7520
  • Bouchon Bakery
    上に書いたBouchon Bistroのベーカリー部門です。パンもありますが、スイーツもあります。もうちょっと種類が多いといいんだけどなぁ...
    _DSC9679 _DSC9707 _DSC9766
  • Bellagio Patisserie
    _DSC6336 _DSC6353
  • Donut Bar
    _DSC5896 _DSC5917

アメリカのレストランでクレジットカードで支払う時、一度カードを持って行ってレシートを持ってきてくれます。そこにチップと合計額を書いて、サインをして完了なんですけど、それがめんどうくさい。

チップのないフランスやシンガポールだと、店員さがハンディターミナルを持ってきて、タッチ機能がついていればピッとタッチすればそれでおしまい。アメリカはチップあるし、こうはできないよなぁと思っていたのですが、Bardo Brasserieではじめてハンディターミナルで決済しました。

ハンディターミナルを店員さんが置いていって、ディスプレイにチップのパーセンテージが表示されるので、その中から選択して、後はタッチすればOK。タッチ機能がなければ、暗証番号を入れるのだと思います。

今後、こういう店が増えていくのでしょう。それにしても、チップのパーセンテージの選択肢が決め打ちというのもなんかへんな感じですね。
_DSC0826

買いもの

ラスベガスはショッピングモールやアウトレットもあるので、時間があるのであればそういうところにいけばいいと思います。

アウトレットはちょっと離れているので、バスかタクシー/ライドシェアでしょうね。

さて、問題は日用品です。水とかね。

スーパーとかコンビニ的に使えるのは、以下の2つのショップ。

  • Walgreens
  • CVS
どちらも複数の店舗がJavaOne会場近辺にあります。どちらの店舗ももともとはドラッグストアなのですが、Walgreensの方が食べものなどは多い感じ。バラマキ用のおみやげのお菓子なんかはWalgreensの方がいいかもしれません。


その他

ドルは持って行った方がいい?

ほとんどクレジットカードで支払うので、現金はほとんど使いませんでした。

レストランに複数人で行った時も、クレジットカードを4枚ぐらいまでなら受け付けてくれます。

今回、現金を使ったのは、6人で食事に行った時の支払いと、チェックアウトの日に荷物を預かってもらったので、ポーターに対してのチップぐらい。後は全部クレジットカードでした。

Google Mapsのオフラインマップ

Google Mapsは便利なので、旅行には必需品だと思うのですが、意外に知られてないのがオフラインマップ。

Wi-Fiのあるところで、事前にマップをダウンロードしておけば、ネットが使えない場所でもGoogle Mapsを使うことができますよ。

帰国時

10月の時点では帰国時にMySOSに登録しておく必要があったんですが、11月からはVisit Japan Webに統一されたようです。来年はどうなるのか分からないですね。

ちなみに、Visit Japan Webを使うと、入国審査や税関申告も事前に登録しておくことができます。税関申告の紙を書かなくてもいいというのはいいのですが、使い方がイマイチなんですよね。

申告を事前に行っておくと、2次元バーコードが表示されるので、空港の税関のところでリーダーで読ませて、そのまま出ていけるのですが、導線がイマイチ。出口のところにリーダーを置いておけばいいのにと思いました。

まぁ、でも徐々に改善されるでしょう。


さて、来年のJavaOneは同じくラスベガスのCaesars Forumで9月18日から21日。今年は3日間でしたが、1日増えて4日間の会期に戻ります。

今年はいろいろと準備ができていない様子がありありだったのでしたし、はじめての会場だったこともあり、もうちょっとなんとかならないかなぁというところも多くありました。

来年はラスベガスでも2回目ですし、会期も公開されていますから、今年よりはよくなっているでしょう。

今のところ、私は参加する予定なので、ぜひご一緒に!

2022/09/20

JEPでは語れないJava 19

このエントリーをはてなブックマークに追加

半年ぶりのJavaのアップデートで、Java 19がリリースされます。

Java 19はJava 18よりJEPは少なく、しかもPreviewやIncubatorでないJEPはJEP 422のLinux/RISC-V Portしかありません。こんなアップデートは初めてかも。

  • 405: Record Patterns (Preview)
  • 422: Linux/RISC-V Port
  • 424: Foreign Function & Memory API (Preview)
  • 425: Virtual Threads (Preview)
  • 426: Vector API (Fouth Incubator)
  • 427: Pattern Matchning for switch (Third Preview)
  • 428: Structured Concurrency (Incubator)

JEP 424のForeign Function & Memory APIは、Java 18まではIncubatorだったのですが、なぜかPreviewに変更されました。今までのFFM APIはjdk.incubator.foreignモジュールから、java.baseモジュールに変更されて、パッケージがjava.lang.foreignになったからなのかもしれません。

なお、Java 19からはFFMに関連して、Restricted MethodsがSpecificationに記述されるようになりました。Javaが管理していないメモリへのアクセスするAPIなどがRestricted Methodsに指定されています。

JEP 426 Vector APIはなかなかIncubatorが外れずにFouthまで行ってしまいました。なかなか難しいですね。

JEP 427 Pattern Matching for switchもThird Previewです。JEP 405 Record Patternsはinstance ofでRecordのプロパティを直接扱えるようになる機能です。これもinstance ofの後はswitchでも使えるようになるはずなので、Pattern Matching for switchが正式になるのはいつになるのか...

JEP 425 Virtual ThreadsはProject Loomで策定されているAPIで、当初はFiberと呼ばれていたものです。Virtual Threadsが銀の弾丸のように書いてある記事もありますけど、実際はそんなことは全然ないんですけどね。ちゃんと設計されたマルチスレッドのシステムであれば、Virtual Threadsを使わなければならない場面は少ないはずです。

JEP 428 Structed Concurrencyは複数のタスクを例外も含めて扱いやすくするためにStructuredTaskScopeクラスを導入するJEPです。

 

ということで、PreviewやIncubatorがついていないStandard JEPの新機能というのは、Java 19ではないことになってます。しかし、JEPに記述されていないAPIの追加は意外に多いんですよね。

 

今回はjava.baseモジュールなどにPreview JEPのAPIが多く導入されていますが、JEPでの新機能は他にゆずって、ここではPreviewやIncubatorのAPIの説明は省略します。また、java.baseモジュール以外のモジュールの変更は少ないし、普通の開発ではほぼ使われないAPIなので、今回はjava.baseモジュールだけ説明します。例によってセキュリティ系のAPIの変更は櫻庭がよく理解していないので省略します。

 

廃止になったAPI

Java 19では、なんと廃止になったAPIはありません。これも珍しいですね。

 

廃止予定のAPI

Java 19で追加された廃止予定のAPIは、SwingのPluggable Look-and-Feel関連のクラスとメソッドです。

 

クラス

前述したようにSwingのPluggable Look-and-Feel関連のクラスがforRemoval=trueになりました。

  • javax.swing.plaf.basic.BasicMenuItemUI.MouseInputHandler
  • javax.swing.plaf.basic.BasicScrollPaneUI.HSBChangeListener
  • javax.swing.plaf.basic.BasicScrollPaneUI.PropertyChangeHandler
  • javax.swing.plaf.basic.BasicScrollPaneUI.ViewportChangeHandler
  • javax.swing.plaf.basic.BasicScrollPaneUI.VSBChangeListener

 

メソッド

メソッドもSwingのPluggable Look-and-Feel関連です。

  • javax.swing.plaf.basic.BasicDirectoryModel.intervalAdded
  • javax.swing.plaf.basic.BasicDirectoryModel.intervalRemoved
  • javax.swing.plaf.basic.BasicDirectoryModel.lt
  • javax.swing.plaf.basic.BasicToolBarUI.createFloatingFrame

 

追加されたAPI

Java 19で追加されたAPIはかなり多いのですが、半分以上はFFM APIです。とはいうものの、FFM以外でもかなり多くのAPIが追加されています。

 

java.base/java.ioパッケージ

java.ioパッケージではシリアライゼーション関連の例外のコンストラクタが追加されました。なぜ、今、これらのコンストラクタが追加されたのかはよく分かりません。

 

InvalidClassException例外

例外の原因を示すcauseがコンストラクタ引数で指定できるようになりました。

  • InvalidClassException(String reason, Throwable cause)
  • InvalidClassException(String cname, String reason, Throwable cause)

 

InvalidObjectException例外

こちらも同じく、例外の原因を示すcauseがコンストラクタ引数で指定できるようになりました。

  • InvalidObjectException(String reason, Throwable cause)

 

ObjectStreamException例外

こちらも同じです。

  • ObjectStreamException(String message, Throwable cause)
  • ObjectStreamException(Throwable cause)

 

java.base/java.langパッケージ

java.langパッケージも多くのAPIが追加されていますが、Virtual Thread関連のものが多いため、それ以外のAPI変更を説明します。

 

Character.UnicodeBlockクラス

Java 19ではUnicode 14.0をサポートするようになりました。

Unicode 14.0というと敬礼の絵文字などが使えるようになっています。しかし、それ以外にも古代アルバニア文字やインドなどで使われているらしいTangsa語の文字などが追加されています。そのためにBlockとScriptも追加されています。

  • ARABIC_EXTENDED_B
  • CYPRO_MINOAN
  • ETHIOPIC_EXTENDED_B
  • KANA_EXTENDED_B
  • LATIN_EXTENDED_F
  • LATIN_EXTENDED_G
  • OLD_UYGHUR
  • TANGSA
  • TOTO
  • UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED_A
  • VITHKUQI
  • ZNAMENNY_MUSICAL_NOTATION

 

Character.UnicodeScriptクラス

こちらも同じく、Unicode 14.0で追加されたScriptが追加されています。

  • CYPRO_MINOAN
  • OLD_UYGHUR
  • TANGSA
  • TOTO
  • VITHKUQI

 

note: 以下の説明はJava 19ではなくて、Java 20の機能でした。Satoさん、ご指摘ありがとうございます。

APIの変更ではないのですが、java.text.BreakIteratorクラスの実装が拡張されて結合文字の絵文字に対応できるようになっています。

今までは正規表現の\b{g}で分解するしかなかったのですが、BreakIteratorクラスのgetChracterInstanceメソッドでできるようになったようです。詳しくはJBSのJDK-8291660をご覧ください。

   - ここまで -

 

Doubleクラス

定数が1つ追加されていますが、これはJLS 4.2.3で定義されている浮動小数点のNを表すものです。

  • PRECISION

PRECISIONはintで定義されていて、doubleでは53になっています。

 

Floatクラス

FloatクラスもDoubleクラスと同じく、JLS 4.2.3で定義されている浮動小数点のNを表す定数が追加されました。

  • PRECISION

floatでは24に定義されています。

 

Integerクラス/Longクラス

まさかIntegerクラスにメソッドが追加されるとは思いもよりませんでした。

  • static int compress(int i, int mask)
  • static int expand(int i, int mask)

Longクラスの場合は引数と戻り値の型がlongになります。

compressはmaskのビットが立った桁のみを残して、取り除いた桁は詰めて表現した数にします。Javadocにある例は

jshell> int compress = Integer.compress(0xCAFEBABE, 0xFF00FFF0)
compress ==> 830379

jshell> System.out.printf("%X%n", compress)
CABAB

maskがFF00FFF0 (1111 1111 0000 0000 1111 1111 1111 0000)なので、16進のCAFEBABEの1になっているビット桁だけにすると CA は残って FE は削除、BAB が残って E が削除。残った部分をくっつけると CABAB となるわけです。

expandメソッドは逆にマスクのビットが立っている桁に、ビットを置きなおす感じです。

jshell> int ex = Integer.express(0xCABAB, 0xFF00FFF0)
ex ==> 211860144

jshell> System.out.printf("%X%n", ex)
CA00BAB0

この演算は下位ビットから当てはめていくので、ビットの立っている箇所だけではiが表されない場合、上位ビットが省略されてしまうようです。

jshell> int ex = Integer.express(0xCABAB, 0x0000FFF0)
ex ==> 47792

jshell> System.out.printf("%X%n", ex)
BAB0

 

Mathクラス/StrictMathクラス

定数にτが追加されました。

  • static final double TAU

τは円の半径に対する円周長の比になり、値としては2πになります。

jshell> Math.TAU
$1 ==> 6.2831853071795

 

Threadクラス

ThreadクラスにはVirtual Thread関連のAPIが増えていますが、それ以外にもいくつかメソッドが追加されました。

  • boolean join(Duration duration)
  • void sleep(Duration duration)
  • long threadId()

joinメソッドとsleepメソッドはタイムアウトをミリ秒で設定できましたが、Java 19で任意の単位の時間で指定できるようなオーバーロードが追加されました。

threadIdメソッドはスレッドのIDを取得するためのメソッドです。

 

java.base/java.mathパッケージ

BigDecimalクラスに定数が追加されました。

 

BigDecimalクラス

2を表す定数が追加されています。

  • BigDecimal TWO

 

BigIntegerクラス

パラレルに乗算を行うメソッドが追加されています。

  • BigInteger parallelMultiply(BigInteger val)

this×valを行う演算ですが、数値が千を超えるようなビット数の場合、処理をパラレルで行います。

 

java.base/java.textパッケージ

DecimalFormatSymbolsクラスにメソッドが追加されました。

 

DecimalFormatSymbolsクラス

ロケールを返すメソッドが追加されています。

  • Locale getLocale()
jshell> var symbols = DecimalFormatSymbols.getInstance()
symbols ==> java.text.DecimalFormatSymbols@f6cadb1e

jshell> symbols.getLocale()
$1 ==> ja_JP

 

java.base/java.time.chronoパッケージ

ISO 8601準拠かどうかを返すメソッドが追加されました。

 

Chronologyインタフェース

暦がISO 8601に準拠しているかどうかを返すメソッドが追加されました。

  • defualt boolean isIsoBased()

デフォルトではfalseを返しますが、ISOChronologyクラスなどはtrueを返します。JapaneseChronologyクラスなどもtrueを返します。ただし、太陰暦であるヒジュラ暦を表すHijrahChronologyクラスはfalseを返します。

 

java.base/java.time.formatパッケージ

ロケール指定に関してのメソッドが追加されています。

 

DateTimeFormatterクラス

ローカライズしたパターンの生成を行うメソッドが追加されました。

  • DateTimeFormatter ofLocalizedPattern(String requestedTemplate)

今までofPatternメソッドでロケールを渡すことで同じようなことができましたが、このメソッドはISO 8601準拠の暦をしようすることが前提となっているようです。引数のrequestedTemplateには通常のDateTimeFormatterのフォーマットとは異なり、正規表現で記述するようになっています。使用できる正規表現はJavadocに記載されています。

また、ResolverStyleがSMARTになります。

 

DateTimeFormatterBuilderクラス

こちらも、ロケールに応じたビルダー生成のメソッドが追加されました。

  • DateTimeFormatterBuilder appendLocalized(String requestedTemplate)
  • String getLocalizedDateTimePattern(String requestedTemplate, Chronology chrono, Locale locale)

appendLocalizedメソッドは、DateTimeFormatter.ofLocalizedPatterメソッドのために作られたメソッドのようです。ofLocalizedPatterメソッドの実装で使われていました。

getLocalizedDateTimePatternメソッドはofLocalizedPatternメソッドで指定した正規表現のrequestedTemplateから通常のDateTimeFormatterクラスで使われるパターンを取得するためのメソッドのようです。

 

java.base/java.utilパッケージ

 

HashMapクラス, LinkedHashMapクラス, WeakHashMapクラス, HashSetクラス, LinkedHashSetクラス

マップオブジェクトを生成するためのファクトリメソッドが追加されています。

  • <K, V> HashMap<K, V> newHashMap(int numMappings)

上のnewHashMapメソッドはHashMapクラスで定義されたメソッドです。LinkedHashMapクラスはnewLinkedHashMapメソッド、WeakHashMapクラスはnewWeakHashMapメソッドになります。

同様に、HashSetクラスはnewHashSetメソッド、LinkedHashSetクラスはnewLinkedHashSetメソッドになります。

これらのメソッドはいずれも空のミュータブルなマップオブジェクトを生成します。マップオブジェクトの初期容量は、引数のnumMappingsが負荷係数0.75になるように設定されます。

 

Localeクラス

3種類のファクトリメソッドが追加されています。

  • static Locale of(String language)
  • static Locale of(String language, String country)
  • static Locale of(String language, String country, String variant)

最近のJavaではファクトリメソッドにofが使われるようになっているので、Localeクラスもそれにならったようです。ofメソッドを使う方がキャッシュを使用するので、不要なオブジェクト生成を抑制できます。今後はnewでオブジェクト生成をするのではなく、ofメソッドを使うべきです。

 

Objectsクラス

どこかで見たことのあるはずな表記を作るためのメソッドが追加されました。

  • static String toIdentityString(Object o)

このメソッドを使うと、 型名@ハッシュコード 形式の文字列を作ってくれます。

jshell> var text = "ABC"
text ==> "ABC"

jshell> Objects.toIdentityString(text)
$2 ==> "java.lang.String@b1a58a3"

この形式、Java使っていたら見たことあるはずですよね。toStringメソッドのデフォルトがこの形式の文字列を返します。まぁ、だいたいのクラスはtoStringメソッドをオーバーライドしてしまいますけど。

 

Randomクラス

ファクトリメソッドが1つ追加されました。

  • static Random from(RandomGenerator generator)

RandomGeneratorインタフェースはJava 17で追加されたインターフェースです。RandomクラスはRandomGeneratorインタフェースを実装していますが、乱数生成器を指定することはできませんでした。fromメソッドを使用すると任意の乱数生成器を指定して、Randomオブジェクトを生成することができます。

 

java.base/java.util.concurrentパッケージ

java.util.concurrentパッケージもいろいろと追加されていますが、JEP 425関連のメソッドも多いです。

 

ExecutorServiceインタフェース

やっと、ExecutorServiceインタフェースがAutoClosableになりました!!

  • default void close()

AutoClosableインタフェースを実装しているということは、try-with-resources構文で記述できるようになるということです。今まで使い終わった後にshutdownメソッドをコールしなくてはいけなかったのが、解放されました。

デフォルト実装ではshutdownメソッドをコールして、awaitTerminationメソッドで終わるまで待つ実装になっています。

 

ForkJoinPoolクラス

ForkJoinPoolクラスはExecutorServiceインタフェースを実装しているので、こちらもAutoClosableになっています。それ以外に2つのメソッドが追加されました。

  • default void close()
  • <T> ForkJoinTask<T> lazySubmit(ForkJoinTask<T> task)
  • int setParallelism(int size)

lazySubmitメソッドは、名前の通りsubmitメソッドのlazy版です。最終的には実行されますが、いつ実行されるかはスレッドの空き状況によります。

ForkJoinPoolクラスは生成時に並行度を指定できますが、setParallelismメソッドを使うと後から変更することができます。

 

ForkJoinTaskクラス

ForkJoinTaskクラスには3つのメソッドが追加されました。

  • static <T> ForkJoinTask<T> adaptInterruptible(Callable<? extends T> callable)
  • boolean quietlyJoin(long timeout, TimeUnit unit)
  • boolean quietlyJoinUninterruptibly(long timeout, TimeUnit unit)

adaptInterruptatibleメソッドはadaptメソッドの割り込み可能版です。タスクをcancelメソッドでキャンセルするときに、cancelメソッドの引数のmayInterruptIfRunningをtrueにしておくと、割り込みをかけてキャンセルしてくれます。

quietlyJoinメソッドのオーバーロードはタイムアウトを指定できるようになりました。引数無しのquietlyJoinメソッドは例外をスローしませんが、タイムアウトを指定できるようになったのでInterruptedException例外がスローされる可能性があります。

もう1つのquietlyJoinUninterruptiblyメソッドはquietlyJoinをする時に割り込みをかけないメソッドです。

 

ForkJoinWorkThreadクラス

ForkJoinWorkThreadクラスはFork/Join Frameworで使用するスレッドです。コンストラクタが1つ追加されました。

  • ForkJoinWorkerThread(ThreadGroup group, ForkJoinPool pool, boolean preserveThreadLocals)

今まで提供されていたコンストラクタはForkJoinPoolオブジェクトだけを指定するものでしたが、ThreadGroupとThreadLocalの有無を指定できるようになっています。このコンストラクタはVirtual Threadに関連してそうなんですけど、Previewではないようです。

 

Future.State列挙型

Futureインタフェースに状態を示す列挙型が追加されました。

定数として、以下の4種類が定義されています。

  • CANCELLED
  • FAILED
  • RUNNING
  • SUCCESS

というか、State列挙型のようなものが今までなかったのが不思議だったんですよね。

 

Futureインタフェース

Future.State列挙型の導入に伴い、それを使うメソッドが追加されました。

  • default Throwable exceptionNow()
  • default V resultNow()
  • default Future.State state()

stateメソッドは現在の状態を表すメソッドです。戻り値の方はもちろんFuture.State列挙型です。

resultNowメソッドは結果を取得するメソッドなのですが、getメソッドとは異なって、結果取得を待たないです。つまり、正しい値を取得するには状態がSUCCESSの場合だけです。

デフォルト実装では、その他の状態の場合、IllegalStateException例外がスローされるようになっています。

exceptionNowメソッドも同様に例外の取得を待たないメソッドです。今ままではgetメソッドのExecutionException例外のcauseで原因となる例外を取得していましたが、状態がFAILの場合はexceptionNowメソッドで例外を取得できるようになっています。

デフォルト実装では、その他の状態の場合、同じようにIllegalStateException例外がスローされます。

 

java.base/java.util.spiパッケージ

ToolProviderクラスにメソッドが追加されました。

 

ToolProviderクラス

ToolProviderクラスはServiceLoaderクラスによって呼び出されるクラスなので、普通は使わないとは思いますが...

  • Optional<String> description()

ToolProviderオブジェクトの説明があれば返します。デフォルト実装ではOptional.empty()を返していました。

一応、jar, javac, jlinkの場合の説明がJavadocに記載されているので、興味があれば見てみてください。

 

 

というわけで、Java 19のJEPにのっていないAPIの変更でした。Java 19ではFFM APIやVirtual ThreadsなどのPreviewのAPI変更が多いのですが、意外にもそうでないAPIの変更も多めでした。個人的にはFuture.State列挙型の導入がうれしいですね。

PreviewやIncubatorもいつか紹介したいとは思ってはいます。

2022/03/22

JEPでは語れないJava 18

このエントリーをはてなブックマークに追加

半年ぶりのJavaのアップデートの時間です。

Java 18はLTSの次のバージョンということもあり、JEPは少なめです。

  • 400: UTF-8 by Default
  • 408: Simple Web Server
  • 413: Code Snippets in Java API Documentation
  • 416: Reimplement Core Reflection with Method Handles
  • 417: Vector API (Third Incubator)
  • 418: Internet-Address Resolution SPI
  • 419: Foreign Function & Memory API (Second Incubator)
  • 420: Pattern Matching for switch (Second Preview)
  • 421: Deprecate Finalization for Removal

しかし、日本、特にWindowsの日本語環境で運用しているシステムにとって、とても重大な変更があります。

それが、JEP 400のUTF-8 by Defaultです。

Reader/Writer系のクラスで文字コードを指定しない場合、デフォルトの文字コードとしてUTF-8が使われるようになります。今まで、Windowsの日本語環境ではデフォルトの文字コードはWindows-31j (MS932)だったので、それを前提とした入出力は動作がおかしくなります。

もちろん、互換性維持のための策もちゃんとあって、file.encodingプロパティをCOMPAT、つまり実行時にオプションとして-Dfile.encoding=COMPATを指定すれば今まで通りのデフォルトの文字コードになります。

しかし、デフォルトの文字コードに依存したコードはなるべく早いうちに、文字コードを指定するコードに書き換えるべきです。

なお、NIO.2を使用した入出力はすでにデフォルトの文字コードがUTF-8になっているので、変更は必要ありません。

 

JEP 408は以前よりJDKに含まれていたWeb Server機能を使用できるツールの提供、JEP 413はJavadocにコードを書くために@snippetタグの導入です。

JEP 416はリフレクションの実装方法の改善です。JEP 421は以前より予告されていたfinalizerの廃止です。for Removalになったので、どんなに遅くなったとしても次のLTSではfinalizeメソッドは使えないと思った方がいいです。

他のIncubatorモジュールやPreviewは2ndや3rdなので、もうおなじみ?

 

例によってセキュリティ系のAPIの変更は櫻庭がよく理解していないので、省略します。

 

廃止になったAPI

メソッド

JEP 421関連でfinalizeメソッドが廃止になりました。これらはJava 16でfor Removalになっていたものです。

  • java.awt.color.ICC_Profile.finalize()
  • java.awt.image.ColorModel.finalize()
  • java.awt.image.IndexColorModel.finalize()

いずれもAWT関連なので、特に問題にはならないと思います。

 

廃止予定のAPI

Java 18で追加された廃止予定のAPIは、JEP 421関連のfinalizeメソッドがほとんどだけです。

 

メソッド

JEP 421関連のfinalizeメソッド以外のメソッドとして、とうとうThread.stop()メソッドがforRemovalになりました。stopメソッドを使われていることも少なくなっているとは思いますが、注意が必要です。

また、セキュリティ系の情報を保持するSubjectクラスのdoAsメソッドが廃止予定になりました。

  • java.awt.Graphics.finalize()
  • java.awt.PrintJob.finalize()
  • java.lang.Enum.finalize()
  • java.lang.Object.finalize()
  • java.lang.Runtime.runFinalization()
  • java.lang.System.runFinalization()
  • java.lang.Thread.stop()
  • java.util.concurrent.ThreadPoolExecutor.finalize()
  • javax.imageio.spi.ServiceRegistry.finalize()
  • javax.imageio.stream.FileCacheImageInputStream.finalize()
  • javax.imageio.stream.FileImageInputStream.finalize()
  • javax.imageio.stream.FileImageOutputStream.finalize()
  • javax.imageio.stream.ImageInputStreamImpl.finalize()
  • javax.imageio.stream.MemoryCacheImageInputStream.finalize()
  • javax.security.auth.Subject.doAs(Subject,PrivilegedAction)
  • javax.security.auth.Subject.doAs(Subject,PrivilegedExceptionAction)

 

追加されたAPI

LTSの次のバージョンということもあり、Java 18のAPIの追加はあまりありません。ただし、java.baseモジュールにメソッド追加が多いです。

 

java.base/java.ioパッケージ

java.ioパッケージでは2つのメソッドが追加されましたが、1つはスーパークラスで定義されていたものをオーバライドしたメソッドです。それがFileInputStreamクラスのtransferToメソッドです。

もう1つのメソッドがJEP 400に関連したメソッドです。

 

PrintStreamクラス

PrintSreamクラスでは現在使用している文字セットを返すcharsetメソッドが追加されました。

  • Charset charset()

Java 17でCosoleクラスにcharsetメソッドが追加されましたが、同じようにファイルに出力を行う文字セットを返します。

 

java.base/java.langパッケージ

java.langパッケージではMathクラスとStrictMathクラスにメソッドが追加されました。いずれも同じメソッドなので、一緒に説明します。

Mathクラス/StrictMathクラス

Math/StrictMathクラスでは、それぞれ13のメソッドが追加されました。

  • int ceilDiv(int x, int y)
  • long ceilDiv(long x, int y)
  • long ceilDiv(long x, long y)
  • int ceilDivExact(int x, int y)
  • long ceilDivExact(long x, long y)
  • int ceilMod(int x, int y)
  • int ceilMod(long x, int y)
  • long ceilMod(long x, long y)
  • int divideExact(int x, int y)
  • long divideExact(long x, long y)
  • int floorDivExact(int x, int y)
  • long floorDivExact(long x, long y)
  • long unsignedMultiplyHigh(long x, long y)

Exactがつくメソッドは、ArithmeticException例外を投げるという違いだけなので、それ以外のメソッドを説明します。

ceilDiv系のメソッドは演算結果より大きいもしくは同じになる最小の整数を返します。

jshell> Math.ceilDiv(10,3)
$1 ==> 4

jshell> Math.ceilDiv(9, 3)
$2 ==> 3

jshell> Math.ceilDiv(-10, 3)
$3 ==> -3

ceilMod系の割り算の余りなのですが、負の値になることもあります。つまり、z = Math.ceil(x, y)だったときに、ceilModメソッドの返り値はx - z * yになります。

jshell> Math.ceilMod(10,3)
$1 ==> -2

jshell> Math.ceilMod(9, 3)
$2 ==> 0

jshell> Math.ceilMod(-10, 3)
$3 ==> -1

unsignedMultiplyHighメソッドはmultiplyHighメソッドの符号なし版です。

 

java.base/java.net.spiパッケージ

JEP 418でインターネットアドレスの名前解決がSPI化され、それに応じて4つのインタフェース/クラスが追加されました。

  • InetAddressResolverインタフェース
  • InetAddressResolver.LookupPolicyクラス
  • InetAddressResolverProviderインタフェース
  • InetAddressResolverProvider.Configurationクラス

これで独自の名前解決クラスを実装することができるようになります。

 

java.base/java.nio.charsetパッケージ

Charsetクラスにメソッドが1つ追加されています。

Charsetクラス

指定された文字セットを返すforNameメソッドがオーバーロードされました。

  • Charset forName(String charsetName, Charset fallback)

今までのforNameメソッドは指定された文字セットがない場合、IllegalCharsetNameException例外を投げます。これに対し、Java 18で追加されたforNameメソッドは文字セットがない場合、第2引数のfallbackが戻ります。

今までは文字セットがなかった場合は例外処理で処理しなくてはならなかったのが、fallbackを指定できるのでコードが分かりやすくなるはずです。

 

java.base/java.timeパッケージ

Durationクラスにメソッドが1つ追加されています。

Durationクラス

Durationクラスは時間間隔表すクラスですが、保持している時間間隔が正の値なのか調べるためのメソッドが追加されました。

  • boolean isPositive()

isZeroメソッドと、isNegativeメソッドはあったので、これで3つ揃いました。

 

java.net.http/java.net.httpパッケージ

HTTPリクエストを作成するBuilderクラスにメソッドが1つ追加されています。

HttpRequest.Builderクラス

HTTPリクエストを作成するBuilderクラスは、これまでHTTPメソッドのGET, POST, PUT, DELETEを作成するメソッドはあったのですが、HEADを作成するメソッドはありませんでした(HEADメソッドのリクエストを作ることはできます)。そこで、HEADメソッドが追加されています。

  • HttpRequest.Builder HEAD()

これまで、HEADメソッドはmethodメソッドで作らなくてはならなかったのが、少し簡単になりました。

 

java.xml/javax.xml.xpathパッケージ

なぜ、この時期にXPathにメソッドが追加されたのか全然わからないのですが、XPathのファクトリにメソッドが2つ追加されました。

XPathFactoryクラス

XPathFactoryクラスで属性を設定、取得するメソッドが追加されました。

  • String getProperty(String name)
  • void setProperty(String name, String value)

追加されたのはいいのですが、使い道がよく分かりません。デフォルトの実装ではUnsupportedOperationException例外が投げられるようになっています。

 

java.compilerモジュール

毎度のことですが、java.compilerモジュールはいろいろと追加されています。いつものソースバージョンやらなにやらが大半ですが、アノテーション処理関連でも少しだけメソッドが追加されています。とはいうものの、普通は使わないので省略します。

 

ということで、Java 18のAPIの変更をまとめました。

LTSの次のバージョンということで、変更点は少なめですね。