Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
String Templateによる文字列補間
Search
Yuichi.Sakuraba
November 10, 2023
Technology
4
3.9k
String Templateによる文字列補間
2023-11-11 JJUG CCC セッション資料
String Templateによる文字列補間
Yuichi.Sakuraba
November 10, 2023
Tweet
Share
More Decks by Yuichi.Sakuraba
See All by Yuichi.Sakuraba
JavaにおけるNull非許容性
skrb
2
2.9k
あなたはJVMの気持ちを理解できるか?
skrb
5
5.3k
で、ValhallaのValue Classってどうなったの?
skrb
2
9.3k
Javaにおける関数型プログラミンへの取り組み
skrb
7
500
今こそ、ラムダ式を考える - なぜあなたはラムダ式を苦手と感じるのか
skrb
6
22k
今こそ、ラムダ式を考える - ラムダ式はどうやって動くのか
skrb
7
11k
Project Amberで変わる Javaのプログラミングスタイル
skrb
3
1k
Virtual Threadの動作と効果的な使い方
skrb
2
610
JVMLSに参加してきた
skrb
1
2.1k
Other Decks in Technology
See All in Technology
移行できそうでやりきれなかった 10年超えのシステムを葬るための戦略 / phper-kaigi-2025-ryu
carta_engineering
0
690
どっちの API SHOW?SharePoint 開発における SharePoint REST API Microsoft Graph API の違い / Which API show? Differences between Microsoft Graph API and SharePoint REST API
karamem0
0
110
モジュラーモノリスでスケーラブルなシステムを作る - BASE のリアーキテクチャのいま
panda_program
7
2k
30代エンジニアが考える、エンジニア生存戦略~~セキュリティを添えて~~
masakiokuda
4
2k
DevOps文化を育むQA 〜カルチャーバブルを生み出す戦略〜 / 20250317 Atsushi Funahashi
shift_evolve
1
110
スケールアップ企業のQA組織のバリューを最大限に引き出すための取り組み
tarappo
4
930
Amazon Q Developer 他⽣成AIと⽐較してみた
takano0131
1
120
ソフトウェア開発におけるインターフェイスという考え方 / PHPerKaigi 2025
k1low
9
3.9k
Keynote - KCD Brazil - Platform Engineering on K8s (portuguese)
salaboy
0
120
Symfony in 2025: Scaling to 0
fabpot
2
190
Compose MultiplatformにおけるiOSネイティブ実装のベストプラクティス
enomotok
1
210
Cloud Native PG 使ってみて気づいたことと最新機能の紹介 - 第52回PostgreSQLアンカンファレンス
seinoyu
2
200
Featured
See All Featured
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.4k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
Site-Speed That Sticks
csswizardry
4
450
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
12
1.4k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
Scaling GitHub
holman
459
140k
A better future with KSS
kneath
238
17k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Making Projects Easy
brettharned
116
6.1k
Code Reviewing Like a Champion
maltzj
522
39k
Build The Right Thing And Hit Your Dates
maggiecrowley
34
2.6k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Transcript
String Template による文字列補間 櫻庭 祐一 Java in the Box
Agenda Background JEP 459 String Templates 文字列補間の危険性と Custom Template Processor
Advanced Usage
Background
変数を含んだ文字列連結どうしてる? 1. 変数が少なければ + 演算子 多くなったら StringBuilder 2. String.format or
java.util.Formatter 3. java.text.MessageFormat
を変数で切り替えたい “Hello, World!” World + 演算子 “Hello, ” + name
+ “!”; StringBuilder new StringBuilder(“Hello, ”) .append(name) .append(“!”) .toString(); 変数が多いとコードを読み書きしにくい ...
を変数で切り替えたい “Hello, World!” World String.format() or java.util.Formatter String.format(“Hello, %s”, name);
new Formatter().format(“Hello, %s”, name) .toString(); = java.text.MessageFormat MessageFormat.format(“Hello, {0}”, name); 変数が多いとフォーマット記述子と変数の対応が ...
もっと簡単に まちがいも起こしにくい方法がほしい テンプレートを使った文字列補間 だからといってテンプレートエンジンを使うほどでは ...
もっと簡単に まちがいも起こしにくい方法がほしい テンプレートを使った文字列補間 だからといってテンプレートエンジンを使うほどでは ... もっと手軽に汎用の文字列補間がほしい JEP 459 String Templates
JEP 459 String Templates
String Templates 文字列に 変数 / 式 を埋め込み 文字列補間を行う言語仕様 “Hello, ”
+ name + “!”; STR.”Hello \{name}!”
String Templates の書き方 STR.”Hello \{name}!” テンプレート プロセッサ テンプレート引数 } }
変数 / 式 埋め込み テンプレートプロセッサ java.lang.StringTemplate.Processor 関数型インタフェース processメソッド 標準で提供 STR, FMT, RAW テンプレート引数 文字列リテラル テキストブロック
java.lang.StringTemplate.STR 文字列を生成する最も基本的なテンプレートプロセッサ せずとも使用可能 static import WBSYWBSZ 453za\Y^ a\Z^a\Y Z^z z
z WBSUPEBZ-PDBM%BUFOPX 453zzz 5PEBZJTa\UPEBZ^ a\TXJUDI UPEBZHFU%BZ0G8FFL \ DBTF4"563%": 46/%":l8FFLFOEz EFGBVMUl8FFLEBZz ^^lzz z5PEBZJT 8FFLFOEz
java.util.FormatProcessor.FMT 形式のフォーマットを使用し、 Formatter 文字列を生成するテンプレートプロセッサ WBSYWBSZ '.5zGa\Y^Ga\Z^Ga\YZ^z zz '.5z5PEBZJTU%a\-PDBM%BUFOPX ^z z5PEBZJTz
ロケールを指定する場合 WBSGNU'PSNBU1SPDFTTPSDSFBUF -PDBMFPG KB +1 ʀ GNUz5PEBZJTU"a\-PDBM%BUFOPX ^z z5PEBZJT༵z
java.lang.StringTemplate.RAW 未処理の オブジェクトを生成するプロセッサ StringTemplate WBSYWBSZ 453za\Y^ a\Z^a\Y Z^z 4USJOH5FNQMBUFTU3"8za\Y^ a\Z^a\Y
Z^z 453QSPDFTT TU
String Templates の動作 により実行 invokeDynamic 453z)FMMP a\OBNF^z 要素ごとに分解 z)FMMP l
OBNF lz z)FMMP l OBNFlz -JTU4USJOHGSBHNFOUT -JTU0CKFDUWBMVFT 文字列と値を別々にまとめる WBSTU4USJOH5FNQMBUFPG GSBHNFOUT WBMVFT オブジェクト生成 StringTemplate 453QSPDFTT TU メソッドコール Processor.process
Custom Template Processor 文字列補間の危険性と
Custom Template Processor 特定用途向け Template Processor 文字列以外を返すことも可能 QVCMJDJOUFSGBDF4USJOH5FNQMBUF\ QVCMJDJOUFSGBDF1SPDFTTPS3 &FYUFOET5ISPXBCMF\
3QSPDFTT 4USJOH5FNQMBUFTUSJOH5FNQMBUF UISPXT& TUBUJD51SPDFTTPS5 3VOUJNF&YDFQUJPOPG 'VODUJPO TVQFS4USJOH5FNQMBUF FYUFOET5QSPDFTT \^ ^ ^ 例外を扱うのであれば をオーバーライド process 例外を使用しない場合 をコール of
of メソッドによるカスタマイズ 4USJOH5FNQMBUF1SPDFTTPS4USJOH 3VOUJNF&YDFQUJPOQSPD 4USJOH5FNQMBUF1SPDFTTPSPG TU\ GSBHNFOUT ͱWBMVFT Λ༻ͯ͠هड़ SFUVSO
^
of メソッドによるカスタマイズ と同等の STR Template Processor 4USJOH5FNQMBUF1SPDFTTPS4USJOH 3VOUJNF&YDFQUJPOQSPD 4USJOH5FNQMBUF1SPDFTTPSPG TU\
*UFSBUPS4USJOHJUTUGSBHNFOUT JUFSBUPS WBSTCOFX4USJOH#VJMEFS JUOFYU GPS 0CKFDUPCKTUWBMVFT \ TCBQQFOE PCK TCBQQFOE JUOFYU ^ SFUVSOTCUP4USJOH ^
of メソッドによるカスタマイズ と同等の STR Template Processor 4USJOH5FNQMBUF1SPDFTTPS4USJOH 3VOUJNF&YDFQUJPOQSPD 4USJOH5FNQMBUF1SPDFTTPSPG 4USJOH5FNQMBUFJOUFSQPMBUF
of メソッドによるカスタマイズ 値をすべて大文字に変換 4USJOH5FNQMBUF1SPDFTTPS4USJOH 3VOUJNF&YDFQUJPOQSPD 4USJOH5FNQMBUF1SPDFTTPSPG TU\ WBSWBMVFTTUWBMVFT TUSFBN NBQ
WWUP4USJOH UP6QQFS$BTF UP-JTU SFUVSO4USJOH5FNQMBUFJOUFSQPMBUF TUGSBHNFOUT WBMVFT ^
Processor インタフェースをラムダ式で記述 4USJOH5FNQMBUF1SPDFTTPS4USJOH 3VOUJNF&YDFQUJPOQSPD TU\ GSBHNFOUT ͱWBMVFT Λ༻ͯ͠هड़ ྫ֎Λεϩʔ͢Δ͜ͱՄ SFUVSO
^
Processor インタフェースをラムダ式で記述 を許容しない null Template Processor 4USJOH5FNQMBUF1SPDFTTPS4USJOH /VMM1PJOUFS&YDFQUJPOQSPD TU\ JG
TUWBMVFT DPOUBJOT OVMM \ UISPXOFX/VMM1PJOUFS&YDFQUJPO ^ SFUVSOTUJOUFSQPMBUF ^
Processor インタフェースをラムダ式で記述 を扱う JSON 4USJOH5FNQMBUF1SPDFTTPS+40/0CKFDU 3VOUJNF&YDFQUJPOKTPO1SPD TUOFX+40/0CKFDU TUJOUFSQPMBUF Template
Processor WBSOBNFl4BLVSBCBzWBSDJUZl5PLZPz WBSKTPOKTPO1SPDzzz \ lOBNFzla\OBNF^z lDJUZzla\DJUZ^z ^ lzz
Custom Template Processor のユースケース JSON SQL HTML/CSS/XML ログメッセージ/エラーメッセージ ...
文字列補間の危険性 変数 / 式を埋め込んだ結果が 不適切な表現になることがある SQL インジェクション クロスサイトスクリプティング 4USJOHRVFSZ 4534&-&$5
'30.1FSTPOQ8)&3&QOBNFa\OBNF^ OBNFl4BLVSBCB03QOBNF4BLVSBCBz Custom Template Processor で対応可
Custom Template Processor による対応 使用できない文字をエスケープ 4USJOH5FNQMBUF1SPDFTTPS4USJOH 3VOUJNF&YDFQUJPO130$TU\ -JTU4USJOHWBMVFTTUWBMVFT TUSFBN NBQ
WWUP4USJOH SFQMBDF aa UP-JTU SFUVSO4USJOH5FNQMBUFJOUFSQPMBUF TUGSBHNFOUT WBMVFT ^ 4USJOHOBNF4BLVSBCB03QOBNF4BLVSBCB 4USJOHTRM130$4&-&$5 '30.1FSTPOQ8)&3&QOBNFa\OBNF^ z4&-&$5 '30.1FSTPOQ 8)&3&QOBNF4BLVSBCBa03QOBNFa4BLVSBCBz
Custom Template Processor による対応 使用できない文字があれば例外 4USJOH5FNQMBUF1SPDFTTPS4USJOH *MMFHBM"SHVNFOU&YDFQUJPO130$TU\ TUWBMVFT TUSFBN NBQ
WWUP4USJOH pMUFS WWDPOUBJOT pOE'JSTU JG1SFTFOU T\ UISPXOFX*MMFHBM"SHVNFOU&YDFQUJPO 453*MMFHBM5FYUa\T^ ^ SFUVSOTUJOUFSQPMBUF ^
Custom Template Processor による対応 型による制限 (インスタンス生成時にチェック) SFDPSE1FSTPO 4USJOHOBNF \ ίϯετϥΫλͰνΣοΫ
^ 4USJOH5FNQMBUF1SPDFTTPS4USJOH *MMFHBM"SHVNFOU&YDFQUJPO130$TU\ WBSWBMVFTTUWBMVFT TUSFBN NBQ W\ JG WJOTUBODFPG1FSTPO WBSOBNF \ SFUVSOOBNF ^FMTF\ UISPXOFX*MMFHBM"SHVNFOU&YDFQUJPO 453a\WHFU$MBTT ^a\W^ ^^ UP-JTU SFUVSO4USJOH5FNQMBUFJOUFSQPMBUF TUGSBHNFOUT WBMVFT ^
Custom Template Processor による対応 型による制限 (インスタンス生成時にチェック) 0, WBSQFSTPOOFX1FSTPO 4BLVSBCB
4USJOHTRM130$4&-&$5 '30.1FSTPOQ8)&3&QOBNFa\QFSTPO^ /( WBSOBNF4BLVSBCB 4USJOHTRM130$4&-&$5 '30.1FSTPOQ8)&3&QOBNFa\OBNF^
Advanced Usage
の制限 String Template テンプレート引数 : 文字列リテラル テキストブロック or 453)FMMP a\OBNF^z
文字列リテラル テキストブロック } テンプレート引数をファイルから読み込みたい 文字列リテラルを持つクラスを動的生成
動的テンプレート引数作成 道具 Compiler API Class Loader Re ection or MethodHandle
手順 1. 文字列でクラスのひな型を用意 2. テンプレート引数にする文字列をひな型に埋め込み 3. ひな型をコンパイル 4. コンパイルしたクラスファイルをクラスロード 5. リフレクションもしくは で実行 MethodHandle
動的テンプレート引数作成 QSJWBUFTUBUJD-JTU FYUFOET+BWB'JMF0CKFDUDSFBUF+BWB'JMF0CKFDUT 4USJOHUFNQMBUF \ +BWBͷιʔεͱͳΔจࣈྻ 4USJOHUFNQ4SD453 QVCMJDDMBTT5FNQMBUF\ QVCMJDTUBUJD4USJOH5FNQMBUFQSPDFTT 4USJOHWBSJBCMF
\ SFUVSOKBWBMBOH4USJOH5FNQMBUF3"8aaa a\UFNQMBUF^ aaa ^ ^ クラスのひな型とテンプレートの埋め込み จࣈྻΛιʔεͱ͢Δ+BWB'JMF0CKFDUΛੜ͢Δ +BWB'JMF0CKFDUpMFPCK OFX4USJOH+BWB'JMF0CKFDU 5FNQMBUF UFNQ4SD SFUVSO-JTUPG pMFPCK ^
動的テンプレート引数作成 ίϯύΠϧ͢ΔϑΝΠϧͷ४උ WBSpMFPCKTDSFBUF+BWB'JMF0CKFDUT UFNQMBUF ίϯύΠϥͷऔಘ +BWB$PNQJMFSDPNQJMFS5PPM1SPWJEFSHFU4ZTUFN+BWB$PNQJMFS ԾϑΝΠϧϚωʔδϟͷऔಘ
WBSpMF.BOBHFSDPNQJMFSHFU4UBOEBSE'JMF.BOBHFS OVMM OVMM OVMM ίϯύΠϧλεΫͷੜ +BWB$PNQJMFS$PNQJMBUJPO5BTLUBTLDPNQJMFSHFU5BTL OVMM pMF.BOBHFS OVMM -JTUPG SFMFBTF FOBCMFQSFWJFX OVMM pMFPCKT ίϯύΠϧ UBTLDBMM クラスのコンパイル
動的テンプレート引数作成 Ϋϥεͷϩʔυ WBSMPBEFS$MBTT-PBEFSHFU4ZTUFN$MBTT-PBEFS WBSDMTTMPBEFSMPBE$MBTT 5FNQMBUF .FUIPEΦϒδΣΫτΛऔಘ͠ɺ ϦϑϨΫγϣϯͰ࣮ߦ͢Δ WBSNFUIPEDMTTHFU.FUIPE
QSPDFTT 4USJOHDMBTT 4USJOH5FNQMBUFEZOBNJD5FNQMBUF 4USJOH5FNQMBUF NFUIPEJOWPLF OVMM OFX0CKFDU<>\WBSJBCMF^ クラスのロードと実行
動的テンプレート引数作成 ϑΝΠϧ͔ΒςϯϓϨʔτΛಡΈࠐΈ 4USJOHUFNQMBUFOFX4USJOH 'JMFTSFBE"MM#ZUFT 1BUIPG IFMMPUFNQ ಈతςϯϓϨʔτੜ ୈҾςϯϓϨʔτୈҾςϯϓϨʔτʹຒΊࠐΉจࣈྻ WBSEZOBNJD5FNQMBUF%ZOBNJD5FNQMBUFQSPDFTT
UFNQMBUF #PC%ZMBO ҙͷςϯϓϨʔτϓϩηοαͰॲཧ WBSSFTVMU453QSPDFTT EZOBNJD5FNQMBUF 動的テンプレートの使用例
Conclusion で簡単、簡潔に文字列補間 String Template で拡張可能 Custom Template Processor 文字列補間の危険性も Custom
Template Processor 対応可能
String Template による文字列補間 櫻庭 祐一 Java in the Box