ぺんぎんらぼ

お笑いとマンガ好きなしょぼしょぼWeb系エンジニアの日記です。たまに絵を描きます。

お笑いとマンガ好きなしょぼしょぼWeb系エンジニアの日記です

Spring Boot + Vue.js で作るWebアプリケーション② - 開発環境構築

Vue.jsの開発環境構築

Vue.jsのプログラム構成

Vue.jsは、HTML、JavaScriptCSSを一つのvueファイルというものに記述します。
これだけ聞くと、画面の構成(HTML)、処理の実装(JavaScript)、画面の見た目(CSS)が一つのファイルでごちゃっとしそう・・・と思うかもしれません。
が、実際に書いてみると関連しているものが同じ場所に書かれているので、意外と見通しがいいんです。

当然、このvueファイルはブラウザで表示することができません。vueファイルをコンパイルして、HTML、JavaScriptCSSファイルを生成、ブラウザに表示することになります。
そして、vueファイルをコンパイルするためにNode.jsが必要になります。

Node.jsのインストール

Node.jsの公式ホームページ から、Node.jsのインストーラーをダウンロードします。
LTSでも最新版でも構いませんが、ここではLTSをダウンロードしました。

ダウンロードしたインストーラーを実行します。
Setup画面が表示されるので、[Next]ボタンをクリックします。

ライセンスの画面が表示されるので、[I accept the ~]のチェックボックスをチェックして、[Next]ボタンをクリックします。

インストール先フォルダの指定画面が表示されるので、変更せずに[Next]ボタンをクリックします。

インストールするコンポーネントの指定画面が表示されるので、変更せずに[Next]ボタンをクリックします。

追加のツールインストールの指定画面が表示されます。追加のツールは不要なので、チェックボックスにチェックを入れずに[Next]ボタンをクリックします。

インストールの準備が完了した画面が表示されるので、[Install]ボタンをクリックします。

インストールが開始されます。完了するまで待ちます。

インストールが完了すると完了画面が表示されるので、[Finish]ボタンをクリックしてインストーラーを終了します。

Node.jsのインストール確認

コマンドプロンプトを立ち上げて、nodeコマンドに「--version」オプションを指定して実行します。
正常にインストールされていると以下のような画面が表示されます。

vue/cliのインストール

node.jsがインストールできたら、次にvueのコマンドラインツールであるvue/cliをインストールします。
node.jsでインストールされるnpmコマンドを使用します。「-g」オプションを忘れずに指定します。

npm install -g @vue/cli

vue/cliのインストール確認

コマンドプロンプトからvueコマンドに「--version」オプションを指定して実行します。
正常にインストールされていると以下のような画面が表示されます。

Spring Boot + Vue.js で作るWebアプリケーション① - フロントエンドフレームワークのトレンド

現時点のフロントエンドフレームワークのトレンドは?

SPAを作るときにお世話になるフロントエンドフレームワークは「React」、「AngularJS」、「Vue.js」あたりが有名です。
2022年5月時点で、どのフレームワークが流行っているのか、Google Trendsで調べてみました。

御覧の通り、Reactが圧倒的です。AngularJSは終息傾向、Vue.jsはほぼ横ばいです。
このデータは全世界のトレンドワードなので、次に日本に絞ってみます。

ReactとVue.jsで二分しています。いろいろと調べたところ、Vue.jsはアジア圏で頑張っているようです。
Vue.jsは中国の大企業「アリババ」が開発したことから、アジア圏で人気が高いのでしょう。

Vue.jsはどうなのか

マツキの感覚的には、「AngularJS以上React未満」という感じです。
かなり頑張っていて、コードの見やすさは一番だと思いますが、実行時のランタイムエラーがわかりにくくて、デバッグしにくいです。

それでもVue.jsで行ってみよう!

マツキは職業SEです。お仕事でフレームワーク選定の権利が与えられないことも多々あるので、否応なしにVue.jsで開発することもあると思います。
何より、SEとして日本でトレンドシェアを二分するVue.jsをキャッチアップしておくべき、と思い基本的な使い方までを記事にしていきます。

カメラ、極まる。Xperia PRO-I 写真レビュー

前回の開封レビューに引き続き、今回はカメラが極まったという「Xperia PRO-I」で写真を撮影したので、写真にフォーカスしたレビューをします。
あえて、BASICモードで撮影しました。スマホらしく、パシャ撮りでどこまでの写真が撮れるかの確認です。

以前に使っていたGalaxy S10との比較となります。

ちなみに、マツキは過去、コンパクトデジカメ5台、一眼レスデジカメ1台を所持していたぐらいのカメラ好きです。

風景写真

あえて逆光になるポジションで撮影しました。

f:id:penguinlabo:20211221141322j:plain f:id:penguinlabo:20211221141338j:plain
Xperia PRO-I Galaxy S10

Xperia PRO-Iはフレアが抑えられていて、像がぼやけることなく撮影できています。
レンズ面の反射を防ぐTessarのT*コーティングが生きているんだと思います。
また、左の細かな枝の部分を拡大するとわかるんですが、Xperia PRO-Iの方がフリンジが抑えられている感じがします。

近接撮影

F2.0

まずは、F2.0による撮影です。Galaxy S10はポートレートモードで背景をぼかしています。

f:id:penguinlabo:20211221142403j:plain f:id:penguinlabo:20211221142701j:plain
Xperia PRO-I (F2.0 iso100) Galaxy S10 (ポートレート)

Xperia PRO-Iのほうが、ボケが強いです。
色合いは、やはりよく言われるよう、Galaxyは盛った色調で、Xperiaは見たままの色を再現している感じです。葉っぱの緑部分を見るとわかりやすいです。Galaxyは鮮やかな緑だけど、若干、作り物っぽい。Xperiaは本物っぽいけど、くすんだ色味になります。

また、背景をよく見ると、Galaxyは光が反射しているとことに光の玉のオーブが表れてます。左上の手すり部分がわかりやすいです。

F4.0

次にF4.0による撮影です。Galaxy S10は通常の写真モードでの撮影です。

f:id:penguinlabo:20211221143719j:plain f:id:penguinlabo:20211221143745j:plain
Xperia PRO-I (F4.0 iso100) Galaxy S10 (写真)

色味の傾向はF2.0と変わらないです。ボケ感はあまり変わりはなく、差は少ないですね。

引き撮影

次は引きで撮影したスカイツリーです。ディテールがどこまで保たれているのかを確認するために、一部分を切り出して400%に拡大しています。

f:id:penguinlabo:20211221145741j:plain f:id:penguinlabo:20211221145753j:plain
Xperia PRO-I Galaxy S10

どちらも大差はないですが、細かいところを見ると、Xperiaの方が高精細でシャープさを保っています。

次の画像は建物の壁部分の拡大です。

f:id:penguinlabo:20211221150550j:plain f:id:penguinlabo:20211221150600j:plain
Xperia PRO-I Galaxy S10

Galaxyの方はノイズリダクションが強いのか、のっぺりとした壁になって、質感が失われてる感じです。
ノイズリダクションが強いと質感が失われる欠点はありますが、ISO感度を上げた時のノイズを低減する利点もあるので、どちらがいいかは撮影シーンによるのかなと思います。

総評

Xperia PRO-IとGalaxy S10の日中の写真を比較しました。パシャ撮りでありながら、どちらも結構キレイと感じました。このレベルであれば、一般の人はどちらの機種でも満足するんではないでしょうか。
逆光など、光が強いシーンではXperia PRO-Iが有利です。TessarのT*コーティングがうまく機能しているんでしょう。

普通のスマホと同じ撮影スタイルのBASICモードでもきれいな写真が取れますし、マニュアルでいろいろと調整して、よりきれいな写真を撮ることもできます。
カメラ好きのためのスマホ、という感じですね。

今回の撮影で気になった点としては、「Xperia 1 III」から言われていることですが、日中の晴天の下では最大輝度にしても画面が暗くて見づらいです。
画面の輝度、色合いは、もう少し頑張ってほしいです。4K OLEDがもったいない。ガンバレ、ソニーさん!

カメラ以外の部分で、作りこみの甘さや不満点があるので、PRO-Iに限らずXperiaは万人が満足するものではないと感じました。国内メーカースマホの最高峰だとは思うので頑張ってほしい!
現時点では、一般の人はGalaxy S21、カメラ全振りのスマホが欲しい人はXperia PRO-Iという感じです。カメラ好きのマツキはPRO-I好きです。

カメラ、極まる。Xperia PRO-I 開封レビュー

カメラが極まったと話題の「Xperia PRO-I」買っちゃいました!

ソニーストアで198,000円(税込)と、そこそこハイスペックなパソコンが買えそうな価格です。

人を選ぶスマホで、一般人のマツキは「Xperia 1 III」を買った方がいいのは明らかでしたが、1.0型センサーの迫力に負けて、ポチっちゃいました。

ということで、発売日である2021/12/15に届いたので、さっそく開封していきます。
使ってみないとわからない不満点もぶちまけるので、購入を検討している方は参考にしていただければと思います。

開封の儀

f:id:penguinlabo:20211218233115j:plain

ソニーの白くてシンプルな箱です。

f:id:penguinlabo:20211218233211j:plain

開けると保護シールが張られた本体が出てきます。

f:id:penguinlabo:20211218233552j:plain

同梱物は、取扱説明書、スタートアップガイド、保証書のみで、USB充電アダプターなどは入ってません。

f:id:penguinlabo:20211218233723j:plain

そして本体。重量200gを超えるので、ずっしりと重量を感じます。

f:id:penguinlabo:20211218233943j:plain

まさに目玉の1.0型センサー。存在感もそうですが、本体からそこそこの高さ分、飛び出てます。確実に1円玉1枚以上の厚さの段差があります。

ここだダメだよXperia PRO-I

ちょっと触ってみて、気になった点、不満点をぶちまけていきます。

液晶の発色はそんなに良くない

今まで使用していたGalaxy S10との比較です。

f:id:penguinlabo:20211218235420j:plain

上がGalaxy S10、下がXperia PRO-Iです。
Xperia PRO-Iは白っぽいというか、色が浅いです。画質設定でクリエイターモードにしても、ほとんど変わらず。
解像度は高いんですが、発色は大人し目というよりは、色あせた感じになります。

Xperia 1 IIIも同じだと思うので、購入を検討している人は店頭でGalaxyと比較することをお勧めします。

画面の大きさはそんなに大きくない

画面の大きさは6.5インチですが、そこまで大きく感じません。
というのも、比率が21:9の縦長ディスプレイだからです。
先程のGalaxy S10との比較画像を見てください。Galaxy S10は6.1インチですが、写真のサイズがほぼ、一緒であることがわかります。

幅が小さいことで持ちやすい、ワイドであることでカメラアプリの操作部分が大きくなり、操作しやすいなどの利点もあるので、21:9の比率が一概にデメリットとは言えませんが、大きな画面でYoutubeとかNetflixの動画を見たい、という人には向かない画面比率です。

ボリュームボタンの位置が不満

Xperiaのボリュームボタンは右側の上寄りについています。縦持ちで右手で持つと親指の位置にあり、持ち替えなくてもボリュームの調整ができます。
では、何が不満かというと、横持でカメラを構えた時です。この画像を見てください。

f:id:penguinlabo:20211219002537j:plain

シャッターボタンは本体の端寄りに配置されていますが、ボリュームボタンは端から離れた位置に配置されています。
ボリュームボタンはカメラ時にズーム倍率の変更として使用します。画面から倍率の変更は可能ですが、BASICモード以外のすべてのモードで画面から倍率変更しようとすると、

  • レンズの変更をタッチ
  • 表示された「>」をタッチ
  • 倍率変更
  • 変更が終わったら、画面の別の部分をタッチ

と4アクションも必要になるので、自然とボリュームボタンを使うことになります。
ただ、ボリュームボタンが本体の端から離れているので、横持ちでは非常に押しづらい。シャッターボタンは押しやすい位置なので、ボリュームボタンももっと端に寄せてほしいところです。

ボリュームボタンは縦持ちの時に押しやすい位置に配置されてます。が、横持でカメラを構えた時に押しやすい位置に配置してほしいです。 キャッチフレーズの「カメラ、極まる。」が泣きます。UIのテストとかしてないのか?と疑います。

充電器との相性がシビア

地味に、一番不満に思うことです。
急速充電の充電器でも、ちょっとでも出力の弱い充電器だと「低速充電」になります。
USB PDでない、一昔前の充電器だと「通常の充電」になります。
問題は、一度でも「低速充電」になると、どんな充電器で充電しても「低速充電」のままなんです。本体を再起動すれば治るんですが、この「低速充電」病は面倒です。
Xperia 1 IIIでも、充電の不具合報告をよく見かけるので、注意が必要です。

Galaxyでは「急速充電」になる充電器でもXperiaでは「低速充電」になりました。せめて「通常の充電」で充電してほしい。そして、強制「低速充電」固定にならないでほしい。
低速充電になる原因の一つとして、Googleの純正アプリ「Digital Wellbeing」が原因との話も上がってますが、「Digital Wellbeing」を無効化しても同じだったので、やはり充電器との相性はシビアなようです。

まとめと次回予告

いろいろと不満はありますが、キャリアスマホの無駄なアプリによる無駄な通知から解放されたので、そこはよかったなと思います。おサイフケータイも使えるし。
例えば、ソフトバンクで下位機種のXperia 1 IIIを買うと、18万8640円です。1万円程度しか差がないのにストレージ容量半分、カメラのセンサーが小さくなる下位機種を買うことになります。なんですかねー、キャリアモデルって。

次回はGalaxy S10とXperia PRO-Iで写真を撮り比べてみようかと思います。「カメラ、極まる。」だそうなので。

GitLabでCI/CD - Javaプロジェクトのビルドとテスト

みなさん、GitLabを使ってますか?

GitLabは、クラウド、オンプレ、Dockerと様々な環境で利用できるGitのリポジトリマネージャーです。
オンプレで利用できることから、社内の開発プロジェクトで利用するケースも多いです。Dockerイメージを使って環境を構築できるのも、お手軽でいいです。

そんな多様性の高いGitLabですが、ただのGitリポジトリだけとして、使ってないですか?
実はGitLabはリポジトリ以外の機能も多く、便利なものが多いです。今回はGitLabの便利機能の中から、CI/CDを紹介します。

GitLabのCI/CDは超簡単!

CI/CDというと、真っ先に思いつくのはJenkinsだと思います。
よくあるJenkinsのユースケースといえば、プロジェクトデプロイ時にビルドとJUnitテストを実行したり、定期的にWebアプリケーションをビルドしてWebサーバにデプロイ、なんてことをすることが多いのではないでしょうか。

GitLabにもCI/CDがあり、Jenkinsと連携せずにGitLab単体でも、Jenkinsと同様のことを実現できます。
今回はGitLab単体で、WebアプリケーションのビルドをJUnitのテストを自動化する方法を説明します。

GitLabでCI/CDを実行する場合、GitLabサーバのほかにGitLabRunnerというものを立ち上げる必要があります。
今回は、GitLabでCD/CDを実行する環境の構築方法については解説しません。

CIの設定 (定義)

CIの動作の定義はGitLab上ではなく、CIを動かすプロジェクト上に定義ファイルを配置して、そのファイルに定義します。
プロジェクトの直下に「.gitlab-ci.yml」というファイル名でファイルを作成して、以下のような内容でCIの動作を定義します。

ファイル「.gitlab-ci.yml」はファイル名が「.」(ドット)で始まるので、eclipseでは隠しファイルと認識され、パッケージエクスプローラーに表示されません。
Ctrl + Shift + Rの「リソースを開く」からファイルを開くか、パッケージエクスプローラーのフィルターから「.*リソース」を表示するように設定します。
image: java:8-jdk

stages:
  - build
  - test

before_script:
  - export GRADLE_USER_HOME=`pwd`/.gradle
  - chmod +x ./gradlew

cache:
  paths:
    - .gradle/wrapper
    - .gradle/caches

build:
  stage: build
  script:
    - ./gradlew assemble
  artifacts:
    paths:
      - build/libs/*.war
    expire_in: 1 week
  only:
    - master
    - develop

test:
  stage: test
  script:
    - ./gradlew check
  artifacts:
    reports:
      junit: build/test-results/test/**/TEST-*.xml

ここでは、タスクとしてプロジェクトをビルドする「build」とテストする「test」の2つのタスクを定義しています。
今回は、詳細の説明は省略しますが、それぞれのタスクの「script」に実行するコマンドを、「artifacts」に実行後の成果物の生成方法を定義します。

CIの実行

プロジェクトに作成した「.gitlab-ci.yml」をGitにPUSHすると、自動的にCIが実行されます。
CIの実行状況を確認するには、GitLabのプロジェクトのページから、ロケットアイコンのCI/CD - Pipelinesをクリックします。

f:id:penguinlabo:20211103205617p:plain

パイプライン一覧が表示され、Statusがrunningとなっており、パイプラインが実行されていることがわかります。 このページの「Tests」タブから、JUnitの実行結果を確認することもできます。

f:id:penguinlabo:20211103205644p:plain

パイプライン一覧から、Pipeline IDのリンクをクリックすると、パイプラインの詳細画面が表示されます。 このページから成果物のダウンロードも可能で、例えば、Webアプリケーションのビルドであれば、warファイルをダウンロードすることができます。

f:id:penguinlabo:20211103205721p:plain

まとめ

いかがだったでしょう。GitLab CI/CDを実行できる環境さえ用意してしまえば、CI/CDの定義ファイルを作るだけで、CI/CDを実行できることがわかると思います。
基本的なことは簡単に、頑張れば凝ったこともできるものなので、まずは、今回の紹介のようにビルド&テストを試して、手軽さを実感していただきたいです。

QNAPのiSCSIはローカルHDDの代替になるか?

マツキは普段、ノートPCを使ってますが、重い処理をするためのデスクトップPCも使ってます。
で、そのデスクトップPCは、システムドライブはSSDですが、大きなデータ、例えば動画ファイルなんかを置くためにHDDも搭載しています

使っているHDDはこれ。

容量は2TBで回転数が5400rpmのHDDです。

購入当時は十分な容量で、5400rpmというのも、ごくごく普通のHDDでした。

容量が足りない! なんかもっさり!

このHDDにいろんなデータをため込んでいるので、最近、空き容量が減ってきたと感じました。
それに、複数の作業で同時にHDDにアクセスすると、速度が遅く、ストレスを感じるようになりました。
例えば、ファイルをコピーしながら動画を編集すると、動画のサムネイル表示がなかなか更新されず、もっと快適な環境にしたいなーと感じることが多々あります。

そういえば、iSCSIってどうなんだろう?

前の記事にも書きましたが、マツキ家にはQNAPのNASがあります。
で、このNASにはiSCSIという機能があります。これは、NASのHDDの一部の容量を切り出して、PCのローカルディスクのように使う機能です。

NASは潤沢な容量があるので、容量の問題はクリアできます。問題は速度です。iSCSIはネットワーク接続なので、SATA接続のHDDと比較してどうなのか?という点は気になります。

速度測定

早速、速度測定です。測定環境は以下の通りです。

ローカルディスク

製品 WD20EZRX
容量 2TB
回転速度 5400rpm

NAS

製品 TS-873
容量 10TB × 8 RAID5
ネットワーク速度 1G bps

測定結果は以下の通りです。

ローカルディスク iSCSI
f:id:penguinlabo:20211010223351p:plain f:id:penguinlabo:20211010223403p:plain

すべての項目でローカルHDDよりiSCSIのほうが早いです。
特にランダムアクセスが早いので、いろんな作業を同時に実行しても速度低下が抑えられそう。
シーケンシャルアクセスは120MB/s弱なので、ネットワーク速度の限界に達しているのがわかります。もっと早いネットワーク環境であれば、もっと速度が出そうです。

ちなみに、普通にNASをネットワークドライブに割り当てたときの速度も測定してみました。
iSCSIはネットワークドライブより速度が出やすいということだったのですが・・・

iSCSI ネットワークドライブ
f:id:penguinlabo:20211010223403p:plain f:id:penguinlabo:20211010224450p:plain

残念ながら、iSCSIと比較して優位性はなさそうです。

実際にデータ用ドライブとして使ってみた感想

NASのディスクを使っているということもあり、冗長性もNASの構成に準拠されます。RAID5を組んでいるのでディスク故障が即データ喪失につながらないので、安心感があります。
また、NASのスナップショット機能も使えるので、誤って大事なファイルを削除してしまっても、スナップショットからデータを取り戻すこともできます。

しかし、パフォーマンスはベンチマークで測定したもの通りではありませんでした。
iSCSI単体にアクセスしているのであれば、ベンチマーク通りのスピードが出ている感じですが、iSCSIドライブから、NASにファイルをコピーするとか、ネットでファイルをダウンロードしながらiSCSIドライブにアクセスするような、ネットワークの帯域を圧迫する処理iSCSIドライブのアクセスが重なると、途端に重くなる印象です。

結論

回転数の早い最近のHDDを買うのが一番幸せ。

ネットワークインフラを10Gbpsにアップグレードしたときに、iSCSIを再検討したいと思います。
とはいえ、HDDを買うお金もないので、今の遅くて容量の少ないHDDでもう少し我慢です。

Java Tips - メソッドの復帰値の型を総称型も含めて取得する

f:id:penguinlabo:20210908000148j:plain

Javaでプログラム内からメソッドの情報を取得する場合、java.lang.reflect.Methodクラスを使用して取得することができます。

今回、以下のメソッドの復帰値の型を取得します。

public List<String> getStringList() {
    ・・・
}

メソッドの復帰値の型を取得

java.lang.reflect.MethodクラスのgetReturnTypeメソッドにより、メソッドの復帰値の型を取得することができます。

Class returnType = method.getReturnType();
System.out.println("returnType = " + returnType.getName());

これにより、メソッドの復帰値の型がClassオブジェクトとして取得できます。
このコードの実行結果は以下のようになります。

returnType = java.util.List

メソッドの復帰値の型であるjava.util.Listクラスのクラスオブジェクトが取得できていることがわかります。

メソッドの復帰値の総称型を取得

java.lang.reflect.MethodクラスのgetReturnTypeメソッドでは、メソッドの復帰値の「型」の部分を取得できますが、総称型が取得できません。

総称型の情報を含めてメソッドの復帰値の型を取得する場合、Java5で追加されたjava.lang.reflect.MethodクラスのgetGenericReturnTypeメソッドを使用します。

Type returnType = method.getGenericReturnType();
if (returnType instanceof ParameterizedType) {
    ParameterizedType paramType = (ParameterizedType) returnType;
    Type[] argTypes = paramType.getActualTypeArguments();
    for (int i = 0; i < argTypes.length; i++) {
        System.out.println("returnType argument[" + i + "] = " + argTypes[i]);
    }
}

getGenericReturnTypeメソッドは、復帰値の型の情報だけを取得するのではなく、復帰値の型を総称型の情報を含めて取得するものです。

getGenericReturnTypeメソッドの復帰値はTypeインターフェースです。実際の復帰値はメソッドの復帰値の型によって変わります。
メソッドの復帰値の型が総称型を持つ場合、getGenericReturnTypeメソッドの復帰値はParameterizedTypeインターフェースとなります。このParameterizedTypeインターフェースのメソッドを使用して総称型を取得することになります。

総称型の取得方法

ParameterizedTypeインターフェースのgetActualTypeArgumentsメソッドを使用して、総称型を取得します。

    ParameterizedType paramType = (ParameterizedType) returnType;
    Type[] argTypes = paramType.getActualTypeArguments();

総称型は元クラスによって複数存在する場合があるので、getActualTypeArgumentsメソッドの復帰値は、Typeインターフェースの配列です。
例えば、メソッドの復帰値がListインターフェースの場合、総称型は1つですが、Mapインターフェースの場合、総称型は2つになります。
また、総称型が入れ子になる場合があるので、getActualTypeArgumentsメソッドの復帰値はClassの配列ではなく、Typeインターフェースの配列になっています。

総称型の判定方法

getActualTypeArgumentsメソッドの復帰値は、Typeインターフェースの配列のため、総称型に特定のクラスが指定されていることを判定する場合、一工夫必要です。

以下のコードで、総称型がStringクラスであることを判定できます。

Type[] argTypes = paramType.getActualTypeArguments();
for (int i = 0; i < argTypes.length; i++) {
    if (argTypes[i] instanceof Class && ((Class) argTypes[i]) == String.class) {
        // 総称型がStringクラス
        ・・・
    }
}

総称型がStringクラスの場合、getActualTypeArgumentsメソッドの復帰値はTypeインターフェースを実装したClassクラスになります。
なので、getActualTypeArgumentsメソッドの復帰値がClassクラスであることを判定した後、Classクラスにキャストして、そのClassオブジェクトがStringクラスであることを判定します。

今回のポイント

  1. メソッドの復帰値を総称型を含めて取得する場合、java.lang.reflect.MethodクラスのgetGenericReturnTypeメソッドを使用する。
  2. java.lang.reflect.MethodクラスのgetGenericReturnTypeメソッドの復帰値はTypeインターフェース。
  3. 復帰値のTypeインターフェースは、型の内容によって、Typeインターフェースを継承or実装した、いくつかのクラスに分岐する。

java.lang.reflect.MethodクラスのgetGenericReturnTypeメソッドは詳細な情報が取得できる半面、取得方法が複雑になります。
取得した情報のクラスが取得する内容によって変化することを気にする必要があります。

f:id:penguinlabo:20210907123730p:plain