きっかけ
前回記事でJava13の調査したけど、後々になってTextBlocksに疑問が湧いてきたので調査した
過去記事は、書きを参照
355: Text Blocks (Preview)
JEP 355: Text Blocks (Preview)
ダブルクォートだけを表示させたらどうなるか?
テストコード
public class Jep355Sample2 { public static void main(String[] args) throws Exception { String str = """""""; System.out.println(str); } }
期待値
「"」だけが表示される。
答え
$ javac --enable-preview --release 13 Jep355Sample2.java Jep355Sample2.java:3: エラー: テキスト・ブロックの開始区切り文字のシーケンスが無効です。行の終了文字がありません String str = """""""; ^ Jep355Sample2.java:3: エラー: テキスト・ブロックの開始区切り文字のシーケンスが無効です。行の終了文字がありません String str = """""""; ^
コンパイル時に怒られた。。。
Descriptionをよく読むと、The opening delimiter is a sequence of three double quote characters (""") followed by zero or more white spaces followed by a line terminator.
とある。
「Google翻訳よ、おらに力を分けてくれ~」と思いながら翻訳すると、「開始区切り文字は、3つの二重引用符( "" ")の後にゼロ個以上の空白が続き、行終端文字が続くシーケンスです。」となる。
期待値通りの出力をするには、下記に変えると行ける。
public class Jep355Sample2 { public static void main(String[] args) throws Exception { String str = """ " """; System.out.println(str); } }
テキストブロックに\nを入れたらどうなるか?
public class Jep355Sample3 { public static void main(String[] args) throws Exception { String str = """ hello\nSaga!! """; System.out.println(str); } }
何を表示させようかと迷ったら、とりあえず佐賀。
期待値
そのまま、「hello\nSaga!!」が表示される
答え
$ java --enable-preview Jep355Sample3 hello Saga!!
改行されるだと。。。
Descriptionをよく読むと、たしかになんか書いてある。
The content may include line terminators directly, unlike the characters in a string literal. The use of \n in a text block is permitted, but not necessary or recommended. For example, the text block: """ line 1 line 2 line 3 """ is equivalent to the string literal: "line 1\nline 2\nline 3\n" or a concatenation of string literals: "line 1\n" + "line 2\n" + "line 3\n" If a line terminator is not required at the end of the string, then the closing delimiter can be placed on the last line of content. For example, the text block: """ line 1 line 2 line 3""" is equivalent to the string literal: "line 1\nline 2\nline 3"
ざっくり読むと、「書くこともできるけど、非推奨」的な感じだと思う。
わざわざ「\n」入れるより、改行したほうが楽だろうってことだろうね。。。
たぶん、ほかのエスケープ系の文字も同様の扱いになっている気がする。
疑問
どこでインデントがきまるの?
String str = """ hello Saga!! """;
上記の実行結果は、下記になる。
$ java --enable-preview Jep355Sample4 hello Saga!!
本来なら、文字列の前にインデントようの空白があるのだが、なぜか表示されない。
意図通りだからいいんだけど、どういうルールなのか気になった。
さっきよりインデントを増やしたら、どうなるのか試したら、今度は、追加したインデントが表示された。
String str = """ hello Saga!! """;
$ java --enable-preview Jep355Sample4 hello Saga!!
インデントの位置は、たぶん、もっともインデントが少ないところがベースになるのだろうと予想。
dependenciesをよく読んでいると、2. Incidental white space
に、なんかそれっぽい記述がある。
どうも、インデントの決定は、開始の"""
以降の最小のインデントで決まるっぽい。
タブ文字は、1文字とカウントされるっぽいので、インデントに使う文字列を統一してないと、予期せぬレイアウト崩れになりそう。
TextBlocksのところだけインデントが1行ごとに違うとかは、面倒くさいから誰もやらないとは思うが、Javaのユーザ数は多いから、居そうだな。。。