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
58
あたらしい もじれつの かきかた
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
社内勉強会vol.3@ごーふぁー荘
aya_ebata
0
550
社内勉強会vol.2@ごーふぁー荘
aya_ebata
1
590
社内勉強会vol.1@ごーふぁー荘
aya_ebata
0
530
Other Decks in Technology
See All in Technology
ゼロから始めるVue.jsコミュニティ貢献 / first-vuejs-community-contribution-link-and-motivation
lmi
1
150
IaCジェネレーターとBedrockで詳細設計書を生成してみた
tsukasa_ishimaru
4
900
MixIT 2024 - Pulumi : Gérer son infra avec son langage de programmation préféré
ju_hnny5
1
120
Gitlab本から学んだこと - そーだいなるプレイバック / gitlab-book
soudai
7
1.3k
M&A戦略を支えるデータマネジメント (MIDAS Tech Study #16 GENDA Komiyama)
kommy339
1
120
データベース02: データベースの概念
trycycle
0
180
障害対応をちょっとずつよくしていくための 演習の作りかた
heleeen
1
1.7k
Google Cloud Next '24 Recap(Cloud Run/k8s)
mokocm
0
340
開発パフォーマンスを最大化するための開発体制
ham0215
7
1.2k
Cloud Service Mesh に触れ合う
phaya72
1
250
競技としてのKaggle、役に立つKaggle
yu4u
6
2.4k
【SORACOM UG 東海】あらゆるモノがつながる社会へ、IoT と SORACOM
soracom
PRO
1
150
Featured
See All Featured
Learning to Love Humans: Emotional Interface Design
aarron
267
39k
Code Reviewing Like a Champion
maltzj
515
39k
The Invisible Customer
myddelton
114
12k
VelocityConf: Rendering Performance Case Studies
addyosmani
321
23k
Building Flexible Design Systems
yeseniaperezcruz
320
37k
The Straight Up "How To Draw Better" Workshop
denniskardys
228
130k
Happy Clients
brianwarren
92
6.4k
For a Future-Friendly Web
brad_frost
172
9k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
228
16k
Docker and Python
trallard
35
2.7k
Bash Introduction
62gerente
605
210k
Mobile First: as difficult as doing things right
swwweet
217
8.6k
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オブジェクトを返す -
テンプレートプロセッサはカスタマイズできる