S-JIS[2019-09-22/2020-09-16] 変更履歴

テキストブロック(Java13〜14)

Java13〜14のテキストブロック(プレビュー版)について。


概要

2019/9/17にリリースされたJava13で、プレビュー版としてテキストブロックが使えるようになった。
テキストブロックとは、複数行にまたがる文字列のこと。

テキストブロック 従来の文字列
"""
aaa
bbb
"""
"aaa\nbbb\n"

つまり、改行を含む文字列リテラルが書きやすくなる。
(複数行文字列を書きやすくする為のものであり、\のエスケープを無くすものではない)

2020/3/17にリリースされたJava14ではエスケープ文字が追加された。[2020-03-21]


また、これに伴ってStringクラスにテキストブロック関連のメソッドが追加されている。

Java13では これらのメソッドはいきなり非推奨(@Deprecated(forRemoval=true))だが、テキストブロックはまだプレビュー版なので、これらのメソッドも正式版で変わる可能性があるということだと思われる。

Java14ではDeprecatedアノテーションは削除され、PreviewFeatureアノテーションに置き換わっている。[2020-03-21]


テキストブロックはJava13〜14ではプレビュー版の機能なので、この機能を使いたい場合はコンパイル時にjavacコマンドに--enable-previewを付ける必要があり、
また、実行時にjavaコマンドに--enable-previewを付ける必要がある。
JShellで試す場合もjshellコマンドに--enable-previewを付ける。

> javac --enable-preview --release 13 Example.java
> java --enable-preview Example

テキストブロックの例

テキストブロックは、ダブルクォーテーション3つ「"""」で文字をくくる。

テキストブロックの例 従来の文字列 備考
"""
aaa
bbb
"""
"aaa\nbbb\n" テキストブロックは「"""改行」で始める。
テキストブロック内の改行は、実際の文字列としては文字コード0a(\n)になる。
(Windowsだとテキストブロック内の改行コードが0d0a(\r\n)になる事もあるが、その場合でも0aに変換される)
"""aaa
"""
  テキストブロックを「"""改行」で始めないと(「"""」の直後に文字を続けると)エラーになる。
Example.java:6: エラー: テキスト・ブロックの開始区切り文字のシーケンスが無効です。行の終了文字がありません
"""aaa
   ^
"""
aaa
bbb"""
"aaa\nbbb" テキストブロックの終わりの「"""」の直前には文字列が有っても良い。
(その場合、最終行の末尾は改行されない(\nが無い))
"""
aaa\
bbb
"""
"aaabbb\n" 行末に「\」を置くと、改行されずに行が継続される。(Java14)[2020-03-21]
"""
"""
"" 空文字列。
"""
"a"
"""
"\"a\"\n" テキストブロック内にダブルクォーテーションを含めたい場合、\でエスケープする必要は無い。
(敢えて「\"」と記述することも出来るが)
"""
\"a\"
"""
"""
a\"""
"""
"a\"\"\"\n" ただし、ダブルクォーテーション3つ「"""」をテキストブロックの途中に記述することは出来ないので、
その場合は\でエスケープする必要がある。
"""
aaa\r\n
bbb
"""
"aaa\r\n\nbbb\n" 明示的に\r\nを記述した場合は、\nに変換されずにそのまま残る。
"""
  aa
    bb
  cc
  """
"aa\n  bb\ncc\n" テキストブロック内の各行の先頭に空白(インデント)がある場合、インデントは削除される。
これは、一律に空白を除去するのではなく、最も空白が少ない行の空白文字数分の空白が各行から削除される。
この空白文字数のカウントには、末尾の「"""」しか無い行も含まれる。
なお、空白とはスペース(\u0020)やタブ(\t)等のことであるが、全て(タブも)1文字として計算される。
(タブがスペース4文字分や8文字分であるといった考慮は無い)

(String#stripIndentメソッド参照)
"""
aaa 
bbb 
"""
"aaa\nbbb\n" テキストブロック内の各行の末尾に空白がある場合、その空白は削除される。
左記の例は、見ただけでは分からないがaaaとbbbの右側に空白がある^^;
"""
aaa\s
bbb \s
ccc\s\s
"""
"aaa \nbbb  \nccc  \n" 「\s」を置くと空白に変換される。(Java14)[2020-03-21]

テキストブロック内の各行末の空白を残したい場合は、末尾に「\s」を置けばよい。
(行末にだけ置けば、それ以外の空白も残る)

行頭に「\s」を置いた場合も(インデントとして削除されずに)空白に変換される。
(行の途中に置いても空白になるが、行の途中には元々空白が書けるので、あまり意味は無いか)
"""
  \saa
    b b
  c\sc
  """
" aa\n  b b\nc c\n"
"""
%s v = null;
""".formatted("Object")
"$type v = null;".replace("$type", "Object") テキストブロックには文字列補間(string interpolation)に該当する機能は無い。
String#replaceやformat、あるいはJava13で試験的に導入されたformatted等を使って置換する。
String.format("%s v = null;", "Object")

インデントの除去という処理がある理由は、インデントを含んだ文字列(プログラムの断片等)をテキストブロックで記述する場合、
Javaソースとしてのインデントが余分に入ってしまうので、それを除去する為だと思われる。

		var html = """
		           <html>
		               <body>
		                   <p>サンプル</p>
		               </body>
		           </html>
		           """;

↓(実際の文字列)

"<html>\n    <body>\n        <p>サンプル</p>\n    </body>\n</html>\n"

改行コードの変換・インデントの除去・各行末の空白の除去といった処理はコンパイル時に行われるので、classファイルに含まれるのは処理後の文字列となる。


プレビュー機能へ戻る / Java目次へ戻る / 新機能へ戻る / 技術メモへ戻る
メールの送信先:ひしだま