1. スイッチ式
以前のリリースでは、スイッチ式は「プレビュー」段階の機能にすぎませんでした。 「プレビュー」段階の機能の目的はフィードバックを収集することであることを思い出していただきたいと思います。これらの機能はいつでも変更される可能性があり、フィードバックの結果に基づいて、これらの機能は削除されることもありますが、通常はすべてのプレビュー機能が使用されます。最終的には Java で修正されるでしょう。
(推奨チュートリアル: java 入門プログラム )
新しい switch 式の利点は、デフォルトのスキップ動作 (フォールスルー) がなくなったことです。より包括的で、式や組み合わせが書きやすくなり、バグが発生しにくくなります。たとえば、次に示すように switch 式で矢印構文を使用できるようになりました。
var log = switch (event) { case PLAY -> "User has triggered the play button"; case STOP, PAUSE -> "User needs a break"; default -> { String message = event.toString(); LocalDateTime now = LocalDateTime.now(); yield "Unknown event " + message + " logged on " + now; } };
2. テキスト ブロック
Java 13 で導入されたプレビュー機能の 1 つはテキスト ブロックです。 。テキスト ブロックを使用すると、複数行の文字列リテラルを簡単に作成できます。この機能は Java 14 で 2 回目のプレビューが提供されており、いくつかの変更があります。たとえば、複数行のテキストの書式設定では、多くの文字列連結操作やエスケープ シーケンスを記述する必要がある場合があります。次のコードは HTML の例を示しています:
String html = "<HTML>" + "\n\t" + "<BODY>" + "\n\t\t" + "<H1>\"Java 14 is here!\"</H1>" + "\n\t" + "</BODY>" + "\n" + "</HTML>";
テキスト ブロックを使用すると、このプロセスを簡素化できます。テキスト ブロックの開始タグと終了タグとして三重引用符を使用するだけで、より洗練されたコードを作成できます:
String html = """ <HTML> <BODY> <H1>"Java 14 is here!"</H1> </BODY> </HTML>""";
テキスト ブロックは、通常の文字列リテラルよりも表現力が豊かです。
Java 14 では、2 つの新しいエスケープ シーケンスが導入されています。まず、新しい \s エスケープ シーケンスを使用してスペースを表すことができます。次に、バックスラッシュ \ を使用すると、行末に改行文字が挿入されないようにすることができます。これにより、テキスト ブロック内で長い行を複数の行に分割して読みやすくすることが簡単になります。
たとえば、複数行の文字列を記述する方法は次のようになります:
String literal = "Lorem ipsum dolor sit amet, consectetur adipiscing " + "elit, sed do eiusmod tempor incididunt ut labore " + "et dolore magna aliqua.";
テキスト ブロック内で \ エスケープ シーケンスを使用すると、次のように記述できます:
String text = """ Lorem ipsum dolor sit amet, consectetur adipiscing \ elit, sed do eiusmod tempor incididunt ut labore \ et dolore magna aliqua.\ """;
(ビデオ チュートリアルの推奨事項: java ビデオ チュートリアル )
3.instanceof
のパターン マッチング Java 14 ではプレビュー機能が導入されています。最初にインスタンスの判定を通過し、次に強制変換するコードを作成する必要があります。たとえば、次のコード:
if (obj instanceof Group) { Group group = (Group) obj; // use group specific methods var entries = group.getEntries(); }
このプレビュー機能を使用すると、次のようにリファクタリングできます:
if (obj instanceof Group group) { var entries = group.getEntries(); }
条件付きチェックでは、obj が Group タイプであることが必要なので、なぜこれを含める必要があるのですかコードの最初の部分のように、条件付きコードにそれを含めますか? ブロック内でグループ タイプとして obj を指定するのはどうですか?これによりエラーが発生する可能性があります。
このより簡潔な構文により、Java プログラムのほとんどのキャストを排除できます。
JEP 305 では、この変更について説明し、Joshua Bloch の著書「Effective Java」からの例を示し、次の 2 つの同等の記述方法を示しています。
@Override public boolean equals(Object o) { return (o instanceof CaseInsensitiveString) && ((CaseInsensitiveString) o).s.equalsIgnoreCase(s); }
この段落 コード内でキャストされた冗長 CaseInsensitiveString は、次のようなことができます。
@Override public boolean equals(Object o) { return (o instanceof CaseInsensitiveString cis) && cis.s.equalsIgnoreCase(s); }
このプレビュー機能は、より一般的なパターン マッチングへの扉を開くため、試してみる価値があります。パターン マッチングの考え方は、特定の条件に基づいてオブジェクトからコンポーネントを抽出するための便利な構文を言語に提供することです。条件は型チェックであり、抽出操作には適切なメソッドを呼び出すか、特定のフィールドにアクセスする必要があるため、これはまさに instanceof 演算子の使用例です。
つまり、このプレビュー機能はほんの始まりに過ぎず、将来的にはこの機能によりコードの冗長性がさらに減り、バグの可能性が確実に減少します。
4. 録画
もう 1 つのプレビュー機能は録画です。前に紹介した他のプレビュー機能と同様に、このプレビュー機能も冗長な Java コードを削減する傾向に従っており、開発者がより正確なコードを作成するのに役立ちます。 Record は主に特定のフィールドのクラスに使用され、そのディスプレイスメント機能はカスタム動作なしでデータを保存することです。
早速本題に入り、フィールド クラスの最も単純な例である BankTransaction を取り上げます。これは取引を表し、日付、金額、説明の 3 つのフィールドが含まれています。クラスを定義する際には、考慮すべき多くの側面があります:
Constructor、getter、メソッド toString()、hashCode()、equals() これらの部分のコードは、通常、IDE によって自動的に生成され、たくさんのスペース。生成された完全な BankTransaction クラスは次のとおりです。
public class BankTransaction {private final LocalDate date; private final double amount; private final String description; public BankTransaction(final LocalDate date, final double amount, final String description) { this.date = date; this.amount = amount; this.description = description; } public LocalDate date() { return date; } public double amount() { return amount; } public String description() { return description; } @Override public String toString() { return "BankTransaction{" + "date=" + date + ", amount=" + amount + ", description='" + description + '\'' + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; BankTransaction that = (BankTransaction) o; return Double.compare(that.amount, amount) == 0 && date.equals(that.date) && description.equals(that.description); } @Override public int hashCode() { return Objects.hash(date, amount, description); } }
Java 14 は、この冗長性を解決し、目的をより明確に表現する方法を提供します。このクラスの唯一の目的は、データを統合することです。 Record は、equals、hashCode、および toString メソッドの実装を提供します。したがって、BankTransaction クラスは次のようにリファクタリングできます。
public record BankTransaction(LocalDate date,double amount, String description) {}
レコードを通じて、equals、hashCode、toString の実装、およびコンストラクター メソッドとゲッター メソッドを「自動的に」取得できます。
この例を試すには、プレビュー フラグを使用してファイルをコンパイルする必要があります。
javac --enable-preview --release 14 BankTransaction.javarecord のフィールドは暗黙的に Final です。したがって、レコードフィールドを再割り当てすることはできません。ただし、これはレコード全体が不変であることを意味するわけではなく、フィールドに格納されているオブジェクトは変更可能である可能性があることに注意してください。
5. NullPointerException
一些人认为,抛出NullPointerException异常应该当做新的“Hello World”程序来看待,因为NullPointerException是早晚会遇到的。玩笑归玩笑,这个异常的确会造成困扰,因为它经常出现在生产环境的日志中,会导致调试非常困难,因为它并不会显示原始的代码。例如,如下代码:
var name = user.getLocation().getCity().getName();
在Java 14之前,你可能会得到如下的错误:
Exception in thread "main" java.lang.NullPointerExceptionat NullPointerExample.main(NullPointerExample.java:5)
不幸的是,如果在第5行是一个包含了多个方法调用的赋值语句(如getLocation()和getCity()),那么任何一个都可能会返回null。实际上,变量user也可能是null。因此,无法判断是谁导致了NullPointerException。
在Java 14中,新的JVM特性可以显示更详细的诊断信息:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Location.getCity()" because the return value of "User.getLocation()" is nullat NullPointerExample.main(NullPointerExample.java:5)
该消息包含两个明确的组成部分:
后果:Location.getCity()无法被调用原因:User.getLocation()的返回值为null增强版本的诊断信息只有在使用下述标志运行Java时才有效:
-XX:+ShowCodeDetailsInExceptionMessages
下面是个例子:
java -XX:+ShowCodeDetailsInExceptionMessages NullPointerExample
在以后的版本中,该选项可能会成为默认。
这项改进不仅对于方法调用有效,其他可能会导致NullPointerException的地方也有效,包括字段访问、数组访问、赋值等。
以上がjava14の新機能は何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。