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
あたらしい もじれつの かきかた
Search
Aya Ebata
February 02, 2024
Technology
0
110
あたらしい もじれつの かきかた
2024/02/03 Java女子部
Java 8から21まで いまどきJavaの文法再入門の会!
https://javajo.doorkeeper.jp/events/168055
Aya Ebata
February 02, 2024
Tweet
Share
More Decks by Aya Ebata
See All by Aya Ebata
Flutterハンズオン 5
aya_ebata
0
61
JEP 480: Structured Concurrency
aya_ebata
0
250
Flutterハンズオン 4
aya_ebata
0
100
Flutterハンズオン 3
aya_ebata
0
58
Flutterハンズオン 2
aya_ebata
0
62
Flutterハンズオン 1
aya_ebata
0
95
社内勉強会vol.3@ごーふぁー荘
aya_ebata
0
760
社内勉強会vol.2@ごーふぁー荘
aya_ebata
1
760
社内勉強会vol.1@ごーふぁー荘
aya_ebata
0
700
Other Decks in Technology
See All in Technology
サラリーマンの小遣いで作るtoCサービス - Cloudflare Workersでスケールする開発戦略
shinaps
2
400
COVESA VSSによる車両データモデルの標準化とAWS IoT FleetWiseの活用
osawa
1
260
Terraformで構築する セルフサービス型データプラットフォーム / terraform-self-service-data-platform
pei0804
1
150
250905 大吉祥寺.pm 2025 前夜祭 「プログラミングに出会って20年、『今』が1番楽しい」
msykd
PRO
1
680
サンドボックス技術でAI利活用を促進する
koh_naga
0
200
Aurora DSQLはサーバーレスアーキテクチャの常識を変えるのか
iwatatomoya
1
700
Flutterでキャッチしないエラーはどこに行く
taiju59
0
220
DDD集約とサービスコンテキスト境界との関係性
pandayumi
2
280
AIエージェント開発用SDKとローカルLLMをLINE Botと組み合わせてみた / LINEを使ったLT大会 #14
you
PRO
0
100
La gouvernance territoriale des données grâce à la plateforme Terreze
bluehats
0
150
【初心者向け】ローカルLLMの色々な動かし方まとめ
aratako
7
3.4k
KotlinConf 2025_イベントレポート
sony
1
110
Featured
See All Featured
The Straight Up "How To Draw Better" Workshop
denniskardys
236
140k
Site-Speed That Sticks
csswizardry
10
810
Large-scale JavaScript Application Architecture
addyosmani
512
110k
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.7k
Art, The Web, and Tiny UX
lynnandtonic
302
21k
Build The Right Thing And Hit Your Dates
maggiecrowley
37
2.9k
The Art of Programming - Codeland 2020
erikaheidi
55
13k
Why You Should Never Use an ORM
jnunemaker
PRO
59
9.5k
Building Adaptive Systems
keathley
43
2.7k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.5k
The Power of CSS Pseudo Elements
geoffreycrofte
77
6k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
Transcript
あたらしい もじれつの かきかた 2024/02/03 Java女子部 文法の会! えばた あや @aya_122
自己紹介 - 名前: えばた あや - Twitter: @aya_122 - 好き:
ラーメン二郎 / イクラ / ポケモン - お仕事: フリーランス - Go / React / Python / Vue / Android - 久々にJVM言語のお仕事してるんだ!わーい!Androidだけど!w
今日話すこと JEP 459: String Templates (Second Preview) https://openjdk.org/jeps/459
String Templatesとは - Java 21のJEP 430によってプレビュー機能として提案された - Java 22はSecond Preview
- JEP 459が年始に出てたのでそっちを紹介するよ!
String Templatesとは - Javaの既存の文字列リテラルとテキストブロックを補完する 文字列リテラル String str = "hoge"; ↑ここ!
テキストブロック String json = """ { "name": "web", "version": "1.0.0", } """; ↑"""で囲まれてる部分のこと!
String Templatesとは - テンプレートプロセッサを使用し、式や変数などを埋め込むことで 文字列リテラルを生成する ↓テンプレートプロセッサ STR."Hello \{name}!" ↑式や変数などを埋め込むことができる 今回はこの書き方について詳しく見ていくよ!
String Templatesとは - 現段階ではプレビュー機能なので--enable-previewが必要 実行 $ javac --release 21 --enable-preview
Main.java $ java --enable-preview Main JShell $ jshell --enable-preview
String Templatesを使うと - 変数や式などを含む文字列を簡単に表現できるようになり、可読性を 高める - Java以外の言語で書かれた文字列(SQL、XML、JSONなど)の作成を 簡素化できる
String Templatesの登場人物 STR."My name is \{name}" - テンプレート式: STR."My name
is \{name}" - テンプレートプロセッサ: STR - テンプレート: "My name is \{name} " - 埋め込み式: \{name}
今までの書き方 - 文字列を+演算子で連結する String s = x + " plus
" + y + " equals " + (x + y); -> 読みにくいコードになる…
今までの書き方 - StringBuilderを使う String s = new StringBuilder() .append(x) .append("
plus ") .append(y) .append(" equals ") .append(x + y) .toString(); -> 冗長…
今までの書き方 - String::format や String::formatted を使う String s = String.format("%2$d
plus %1$d equals %3$d", x, y, x + y); String t = "%2$d plus %1$d equals %3$d".formatted(x, y, x + y); -> 文字列とパラメータが分離してしまう…
今までの書き方 - java.text.MessageFormatを使う MessageFormat mf = new MessageFormat("{0} plus {1}
equals {2}"); String s = mf.format(x, y, x + y); -> 多くの式を必要とし、見慣れない構文を使用する… という欠点があったらしい><
String Templatesの書き方 - テンプレート式には色々な種類の値を埋め込むことができる -> 1つずつ見ていくよ!
テンプレート式に文字列を埋め込む STR(テンプレートプロセッサ)を使用して、テンプレート式に 埋め込まれた変数を文字列として表示する String firstName = "Bill"; String lastName =
"Duck"; String fullName = STR."\{firstName} \{lastName}"; System.out.println(fullName); // Bill Duck
テンプレート式に計算式を埋め込む int x = 10, y = 20; String s
= STR."\{x} + \{y} = \{x + y}"; System.out.println(s); // 10 + 20 = 30 - 数値もそのまま使える! - \{...}の中で計算もできる!
埋め込み式からメソッドを呼び出す String getCommunityName() { return "Java女子部"; } void main(){ String
s = STR."今日は\{getCommunityName()}の勉強会"; System.out.println(s); // 今日はJava女子部の勉強会 }
埋め込み式からフィールドにアクセスする record Person(String name, String like) { } void main(){
Person person = new Person("あや", "ポケモン"); String t = STR."\{person.name}です。\{person.like}が好きです。"; System.out.println(t); // あやです。ポケモンが好きです。 }
ダブルクォーテーションを埋め込み式内で使用する String filePath = "tmp.dat"; File file = new File(filePath);
// String old = // "The file " + filePath + " " + (file.exists() ? "does" : "does not") + // " exist"; String msg = STR."The file \{filePath} \{file.exists() ? "does" : "does not"} exist"; System.out.println(msg); // The file tmp.dat does not exist 三項演算子で文字列を表現しやすくなる!
テンプレート式に複数行の処理を埋め込む String time = STR."The time is \{ DateTimeFormatter .ofPattern("HH:mm:ss")
.format(LocalTime.now()) } right now"; System.out.println(time); // The time is 23:21:42 right now(実行した時間)
テンプレート式でインクリメントをする テンプレート式はメソッド呼び出しの引数のように左から右に評価 されるよ! int index = 0; String data =
STR."\{index++}, \{index++}, \{index++}, \{index++}"; System.out.println(data); // 0, 1, 2, 3
埋め込み式内でテンプレート式を入れ子にする String[] fruit = {"apples", "oranges", "peaches"}; String s =
STR."\{fruit[0]}, \{ STR."\{fruit[1]}, \{fruit[2]}" }"; System.out.println(s); // apples, oranges, peaches
テキストブロックでString Templatesを使用する - テキストブロックでも文字列リテラルと同様な書き方で String Templatesを使用できる - HTML、XML、JSON等の文字列を複数行に渡って表示することが できる
例: HTMLで使用 String title = "My Web Page"; String text
= "Hello, world"; String html = STR.""" <html> <head> <title>\{title}</title> </head> <body> <p>\{text}</p> </body> </html> """; System.out.println(html); ↓ <html> <head> <title>My Web Page</title> </head> <body> <p>Hello, world</p> </body> </html>
例: JSONで使用 String name = "Joan Smith"; String phone =
"555-123-4567"; String address = "Anytown"; String json = STR.""" { "name": "\{name}", "phone": "\{phone}", "address": "\{address}" } """; System.out.println(json); ↓ { "name": "Joan Smith", "phone": "555-123-4567", "address": "Anytown" }
FMT - テンプレートプロセッサ(STR以外にもあるよ!) - フォーマット指定子を指定するときに使う(%5dみたいなやつ) - java.util.Formatterで定義されているものと同じフォーマット指定子 を使用する
FMTの例 record Restaurant(String name, double star) {} Restaurant[] restaurants =
new Restaurant[]{ new Restaurant("RamenJiro", 4.5), new Restaurant("Sushiro", 3.4), new Restaurant("Sukiya", 2.2), };
FMTの例 String table = FMT.""" Restaurant Star %-12s\{restaurants[0].name} %4.2f\{restaurants[0].star} %-12s\{restaurants[1].name}
%4.2f\{restaurants[1].star} %-12s\{restaurants[2].name} %4.2f\{restaurants[2].star} \{" ".repeat(5)} Average %4.2f\{ (restaurants[0].star + restaurants[1].star + restaurants[2].star) / 3 } """;
FMTの例 System.out.println(table); ↓ Restaurant Star RamenJiro 4.50 Sushiro 3.40 Sukiya
2.20 Average 3.37
FMTの例 - %-12s: 12桁分用意して左詰め、 文字列 - %4.2f: 4桁分用意して右詰め、小数点以下2桁、小数 その他、いろいろなフォーマット指定子の書き方があるよ! 参考:
https://docs.oracle.com/javase/jp/8/docs/api/java/util/Formatter.html
RAW - テンプレートプロセッサ(これもやで!) - StringTemplateオブジェクトを生成する
RAWの例 String name = "Joan"; String info = STR."My name
is \{name}"; || String name = "Joan"; StringTemplate st = RAW."My name is \{name}"; String info = STR.process(st);
StringTemplate.Processor - StringTemplate.Processorは関数型インターフェース - 関数型インターフェース: 抽象メソッドが1つだけ定義されている インターフェース - 抽象メソッド: 定義だけが記述されているメソッド
- STRとFMTは、StringTemplate.Processorのインスタンスの オブジェクト
StringTemplate.Processor - StringTemplate.Processorは抽象メソッドprocessを実装している -> STRがStringTemplate.Processorのインスタンスのオブジェクト だからSTR.process(st)のように呼べた!
StringTemplateクラス fragmentsとvaluesを持っている! int x = 10, y = 20; StringTemplate
st = RAW."\{x} plus \{y} equals \{x + y}"; String s = st.toString(); System.out.println(s); // StringTemplate{ // fragments = [ "", " plus ", " equals ", "" ], // values = [10, 20, 30] // }
テンプレートプロセッサをカスタマイズする - ファクトリーメソッドのStringTemplate.Processor::ofにラムダ式を 渡すことで、テンプレートプロセッサを作成できる
カスタマイズの例 var INTER = StringTemplate.Processor.of((StringTemplate st) -> { String placeHolder
= "•"; String stencil = String.join(placeHolder, st.fragments()); for (Object value : st.values()) { String v = String.valueOf(value); stencil = stencil.replaceFirst(placeHolder, v); } return stencil; });
カスタマイズの例 String placeHolder = "•"; String stencil = String.join(placeHolder, st.fragments());
st.fragments() -> ["", " plus ", " equals ", ""] "\{x} plus \{y} equals \{x + y}"の文字列だけを配列で返す String.join(placeHolder, st.fragments()) -> "• plus • equals •" placeHolderを区切り文字にして文字列として連結する
カスタマイズの例 for (Object value : st.values()) { String v =
String.valueOf(value); stencil = stencil.replaceFirst(placeHolder, v); } st.values() -> [10, 20, 30] "\{x} plus \{y} equals \{x + y}"の埋め込み式の結果を配列で返す stencil.replaceFirst(placeHolder, v) -> "10 plus 20 equals 30" placeHolderを前から1つずつst.values()の値で置き換えていく
カスタマイズの例 int x = 10, y = 20; String s
= INTER."\{x} plus \{y} equals \{x + y}"; System.out.println(s); // 10 plus 20 equals 30 -> STRのような実装になる!
カスタマイズの例 - StringTemplate::interpolateを使うとさっきの例と同じようなことが できる var INTER = StringTemplate.Processor.of(StringTemplate::interpolate); STRをコードジャンプすると以下だったので同じことだー! Processor<String,
RuntimeException> STR = StringTemplate::interpolate;
テンプレートプロセッサをさらに拡張する - StringTemplate.Processor::ofを使用してテンプレートプロセッサを 作成する場合は、例外をスローしない - StringTemplate.Processorインターフェースを直接使用して実装した テンプレートプロセッサは、例外をスローすることができる - 無効なテンプレートや、途中の処理で失敗した場合などに使える!
StringTemplate.Processorのインターフェース public interface StringTemplate { ... @FunctionalInterface public interface Processor<R,
E extends Throwable> { R process(StringTemplate st) throws E; } ... }
StringTemplate.Processorのインターフェースの実装例 戻り値がJSONObjectでJSONExceptionのExceptionを吐く StringTemplate.Processor<JSONObject, JSONException> JSON_VALIDATE = (StringTemplate st) -> {
(省略) return new JSONObject(jsonSource); }; 上記の実装の途中で以下のExceptionを投げることができるよ throw new JSONException("エラーだよ");
ロケールの変更 - FMTのテンプレートプロセッサはjava.util.FormatProcessorの インスタンスのオブジェクト - FormatProcessorはStringTemplate.Processorを継承している - FMTでの使用時はデフォルトのロケールを使用する - 別のロケールを選択したい場合は、対応したテンプレートプロセッサを
作成できる
ロケールの変更 Date today = new Date(); FormatProcessor JA = FormatProcessor.create(Locale.JAPAN);
String jaStr = JA."今月は%tB\{today}"; System.out.println(jaStr); // 今月は2月 FormatProcessor US = FormatProcessor.create(Locale.US); String usStr = US."This month is %tB\{today}"; System.out.println(usStr); // This month is February
まとめ - テンプレートプロセッサはSTR、FMT、RAWが用意されている - STRは補間した文字列を返す - FMTはフォーマット指定子が使える - RAWはStringTemplateオブジェクトを返す -
テンプレートプロセッサはカスタマイズできる