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
130
あたらしい もじれつの かきかた
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
JEP 526: Lazy Constants
aya_ebata
0
32
Flutterハンズオン 5
aya_ebata
0
85
JEP 480: Structured Concurrency
aya_ebata
0
280
Flutterハンズオン 4
aya_ebata
0
150
Flutterハンズオン 3
aya_ebata
0
89
Flutterハンズオン 2
aya_ebata
0
92
Flutterハンズオン 1
aya_ebata
0
130
社内勉強会vol.3@ごーふぁー荘
aya_ebata
0
780
社内勉強会vol.2@ごーふぁー荘
aya_ebata
1
790
Other Decks in Technology
See All in Technology
スピンアウト講座06_認証系(API-OAuth-MCP)入門
overflowinc
0
1.1k
Windows ファイル共有(SMB)を再確認する
murachiakira
PRO
0
270
「捨てる」を設計する
kubell_hr
0
250
Bref でサービスを運用している話
sgash708
0
190
Phase07_実務適用
overflowinc
0
1.8k
テストプロセスにおけるAI活用 :人間とAIの共存
hacomono
PRO
0
160
Change Calendarで今はOK?を仕組みにする
tommy0124
1
100
FastMCP OAuth Proxy with Cognito
hironobuiga
3
200
モジュラモノリス導入から4年間の総括:アーキテクチャと組織の相互作用について / Architecture and Organizational Interaction
nazonohito51
6
3k
Datadog で実現するセキュリティ対策 ~オブザーバビリティとセキュリティを 一緒にやると何がいいのか~
a2ush
0
130
Agent Skill 是什麼?對軟體產業帶來的變化
appleboy
0
230
「通るまでRe-run」から卒業!落ちないテストを書く勘所
asumikam
2
490
Featured
See All Featured
[SF Ruby Conf 2025] Rails X
palkan
2
850
From π to Pie charts
rasagy
0
160
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
210
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.4k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
The Language of Interfaces
destraynor
162
26k
Bash Introduction
62gerente
615
210k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
120
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
150
The World Runs on Bad Software
bkeepers
PRO
72
12k
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オブジェクトを返す -
テンプレートプロセッサはカスタマイズできる