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.7k
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
あなたはJVMの気持ちを理解できるか?
skrb
5
3.1k
で、ValhallaのValue Classってどうなったの?
skrb
2
8.5k
Javaにおける関数型プログラミンへの取り組み
skrb
7
420
今こそ、ラムダ式を考える - なぜあなたはラムダ式を苦手と感じるのか
skrb
6
21k
今こそ、ラムダ式を考える - ラムダ式はどうやって動くのか
skrb
7
11k
Project Amberで変わる Javaのプログラミングスタイル
skrb
3
980
Virtual Threadの動作と効果的な使い方
skrb
2
580
JVMLSに参加してきた
skrb
1
2.1k
Who's Who in Java
skrb
3
20k
Other Decks in Technology
See All in Technology
ハッキングの世界に迫る~攻撃者の思考で考えるセキュリティ~
nomizone
13
5.2k
Nekko Cloud、 これまでとこれから ~学生サークルが作る、 小さなクラウド
logica0419
2
970
関東Kaggler会LT: 人狼コンペとLLM量子化について
nejumi
3
590
白金鉱業Meetup Vol.17_あるデータサイエンティストのデータマネジメントとの向き合い方
brainpadpr
6
750
【Developers Summit 2025】プロダクトエンジニアから学ぶ、 ユーザーにより高い価値を届ける技術
niwatakeru
2
1.4k
Platform Engineeringは自由のめまい
nwiizo
4
2.1k
Building Products in the LLM Era
ymatsuwitter
10
5.5k
Cloud Spanner 導入で実現した快適な開発と運用について
colopl
1
660
ビジネスモデリング道場 目的と背景
masuda220
PRO
9
520
Moved to https://speakerdeck.com/toshihue/presales-engineer-career-bridging-tech-biz-ja
toshihue
2
740
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
6
57k
『衛星データ利用の方々にとって近いようで触れる機会のなさそうな小話 ~ 衛星搭載ソフトウェアと衛星運用ソフトウェア (実物) を動かしながらわいわいする編 ~』 @日本衛星データコミニティ勉強会
meltingrabbit
0
150
Featured
See All Featured
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7.1k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
46
2.3k
Fashionably flexible responsive web design (full day workshop)
malarkey
406
66k
Designing on Purpose - Digital PM Summit 2013
jponch
117
7.1k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
49k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
12
960
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
133
33k
Facilitating Awesome Meetings
lara
52
6.2k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
160
15k
StorybookのUI Testing Handbookを読んだ
zakiyama
28
5.5k
GraphQLとの向き合い方2022年版
quramy
44
13k
For a Future-Friendly Web
brad_frost
176
9.5k
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