最も一般的な異常なJavaプログラマの顔の一つは、NullPointerExceptionがあります。実行時例外として実行すると、JVMは例外をスローします。
プログラムは、オブジェクトが、見つける必要があるときに我々はすべて知っているように、null
値を、それがNullPointerExceptionがスローされます。1つのシーンのNULLポインタ例外がJavaプログラマは、最も簡単に見過ごさ処理されます。
通常のビジネス・ロジックを進める前に、ヌルポインタ例外処理は、実行時に回避ヌルポインタ例外への応用に必要。不要なNULLポインタ検出コードの存在にこのリード。
ジャワ、Javaでヌルポインタを検出するためにこれらのテンプレートコードに対処するために。8本の紹介新しいタイプOptional<T>
。
オプションを導入することなく前に、どのような問題?
よるオラクル、Javaのオプション8はヌル値を包装するため、コンテナタイプとして導入されるか、または存在しないかであることを特徴とします。オプションで
java.util
有するパッケージfinal
修飾クラス。
私たちは、オプションの出会いを発行するもので、見ていません。
次のメソッドは、私たちのプログラムの中でそれを前提としています。この方法では、スタッフを使用してID
、データベースから従業員の詳細を取得するには:
Employee findEmployee(String id) {
...
};
复制代码
上記の仮定で提供される方法を使用してID
データベースに存在しません。次いで、方法は戻りnull
値。今、私たちは次のコードを書かれている場合:
Employee employee = findEmployee("1234");
System.out.println("Employee's Name = " + employee.getName());
复制代码
値のためにそれを使用する前に、プログラマがNULLポインタ検出ではありませんので、上記のコードNullPointerExceptionが実行時にスローされます。
Javaのオプション8は、液の種類を提供しますか?
さて、聞かせてのは、Java 8の任意の種類は、上記の問題を解決し、助け解消するために導入される方法を見てNullPointerException
異常。
以下は、コードの変更後のコードです:
Optional<Employee> findEmployee(String id) {
...
};
复制代码
上記のコードでは、リターンタイプが変更されますOptional<Employee>
発信者に示すために与えられたID
、対応する従業員が存在しなくてもよいです。
今、私たちは、呼び出し元であるという事実を明確にする必要があります。
呼び出し側は、次のコードを記述する必要があります。
Optional <Employee> optional = findEmployee("1234");
optional.ifPresent(employee -> {
System.out.println("Employee name is " + employee.getName());
})
复制代码
あなたは、私たちは、上記のコードの最初の行の一つ作成していることを確認することができます任意のオブジェクトを。今、私たちは、任意のオブジェクトの上に様々な方法を使用することができます。
上記のスニペットifPresent()
方法は、従業員のみの存在下に設けられたラムダ式と呼ばれています。従業員が存在しない場合は、何も行われません。
のオプションの利点
以下に示すオプションを使用してのいくつかの利点があります:
- 実行時にプログラムがNullPointerExceptionがスローされません。
- プログラムで不要になっNULLポインタ検出されません。
- 簡単に清潔で整然とAPIを開発します。
オプションのクラスメソッド
メソッド 説明 パブリック静的)(空オプショナル このメソッドは、空のオプションオブジェクトを返します。いかなる値は、このオプションのために存在していません。 (T値)のパブリック静的オプション このメソッドはnullではありません指定された値とオプションを返します。 公共の静的なオプションofNullable(T値) このメソッドは、値がnullでない場合、指定値を記述するオプションを返します。それ以外の場合は、空のオプションを返します。 公共Tは(取得) 値は、このオプションに存在する場合、それは値を返します。それ以外の場合は、はNoSuchElementExceptionをスローします。 パブリックブールisPresent() 値が存在している場合、このメソッドはtrueの値を返します。それ以外の場合はfalseを返します。 公共のボイドifPresent(消費者<?スーパーT>消費者) 値が存在する場合、提供された値を持つ消費者が呼び出されます。それ以外の場合は、何もしません。 公共のオプションのフィルタ(述語<?スーパーT>述語) 値が存在し、それはまた、所与の述部に一致する場合、それは値を記述するオプションを返します。それ以外の場合は、空のオプションを返します。 公共のオプションマップ(関数<?スーパーT ,?拡張U>マッパー) 値が存在する場合、マッピング関数が適用され、その結果がNULL値でない場合、それは結果を説明するオプションを返します。それ以外の場合は、空のオプションを返します。 公共のオプションflatMap(機能<?スーパーT、オプションマッパー) 値が存在する場合、それは、それに設けられたオプション支持マッピング関数を適用し、その結果を返します。それ以外の場合は、空のオプションを返します。 公共T orElse(他のT) この方法は、存在する場合の値を返します。それ以外の場合は、他返します。 公共T orElseGet(サプライヤー<?拡張T>その他) この方法は、存在する場合の値を返します。それ以外の場合は、他の呼び出しと呼び出しの結果を返します。 公共T orElseThrow(サプライヤー<?拡張X> exceptionSupplier)は、Xは、Throwableをスローを拡張します 値が存在する場合、この方法は、含まれる値を返します。それ以外の場合は、提供業者によって作成される例外をスローします。 パブリックブールのequals(オブジェクトobj) この方法は、いくつかの他の目的は、このオプション「と等しい」であるか否かを示すために使用されます。 公共int型のhashCode() この方法は、それが存在する場合、現在の値のハッシュコード値を返します。それ以外の場合は、0(ゼロ)を返します。 公共の文字列のtoString() この方法は、単純にデバッグのために適しているオプションの非空の文字列表現を返すために使用されます。
任意のオブジェクトが作成します
このセクションでは、オプションのオブジェクトを作成するための方法を検討します。
1. ヌル値を含む任意のオブジェクトを作成します
次のコードは、NULL値を持つオプションのオブジェクトを作成する方法を示します。示すために使用されるnull
状況を。
Optional <Employee> employee = Optional.empty();
复制代码
null以外の値は、オプションのオブジェクトを持って作成2.
null以外の値を作成するために、どのように次のコードに示すオプションのオブジェクトを持っています。
Employee employee = new Employee("1234", "TechBlogStation");
Optional <Employee> optional = Optional.of(employee);
复制代码
場合ことに注意してくださいOptional.of()
パラメータがnullを提供し、それはすぐにスローされますNullPointerExceptionが発生するので、任意のオブジェクトが失敗します作成し、例外を。
null以外のオブジェクトがあるかどうかを確認するオプション
さて、任意のオブジェクトをチェックするためのさまざまな方法でnull以外の値があるかどうかを学習してみましょう:
1. isPresent()メソッド
null以外の値は、オプションのオブジェクトが存在する場合は、この方法は、isPresent()
それ以外の場合はfalseを返し、trueを返します。
if (optional.isPresent()) {
// optional中有值
System.out.println("Value - " + optional.get());
} else {
// optional中没有值
System.out.println("Optional is empty");
}
复制代码
2.ifPresent()メソッド
プロセスではifPresent()
、我々は、過去の顧客の機能を渡します。場合にのみ、null以外の値オプションのオブジェクト、消費者機能の実装のみが存在します。
オブジェクトがnullの値に保存されているオプションの場合、アクションは実行されません。
optional.ifPresent(value -> {
System.out.println("Value present - " + value);
});
复制代码
上記のコードでは、ラムダの関数として提供するifPresent()
メソッドのパラメータ。
使用get()メソッドは、オプションの値をとります
オプションget()
オプションのオブジェクトから値のみを抽出する方法。あなたは任意のオブジェクトがnull値で保存した場合、それがスローさはNoSuchElementExceptionの例外を。
Employee employee = optional.get()
复制代码
オプションのオブジェクトが格納されている場合、上記のコードで例外がスローされ、ヌルであるが、それは使用することが提案されているget()
従来の方法を、我々は最初に任意の値が存在するか否かを確認しなければなりません。
orElse()メソッドのオプションの使用は、デフォルト値を返します。
あなたが任意のオブジェクトを保存する場合はnull、コールリターンでorElse()
デフォルトとして渡されたメソッドの引数。非ヌル値が格納されている場合、格納された値が返されます。
次の例を参照してください。
// 使用三目表达式返回默认值
User finalEmployee = (employee != null) ? employee : new Employee("0", "Unknown Employee");
复制代码
さて、任意の使用してorElse()
上記と同じロジックを達成するための方法を:
// 使用orElse()方法返回默认值
User finalEmployee = optional.orElse(new Employee("0", "Unknown Employee"));
复制代码
orElseGet()メソッドのオプションの使用は、デフォルト値を返します。
我々はすでにこの方法は、任意のオブジェクトが空の場合ことを知ってorElse()
、デフォルトとしてダイレクトリターン呼び出しパラメータを着信し、orElseGet()
受け入れるサプライヤーをパラメータとして、およびオプションのオブジェクトがnullのときの値サプライヤーをコールするときに保存されました。
サプライヤーの結果は、オプションのデフォルト値が返されます。
User finalEmployee = optional.orElseGet(() -> {
return new Employee("0", "Unknown Employee");
});
复制代码
ヌル値に保存されているオプションの場合は、例外がスローされます
オプションのオブジェクトが空の場合は、使用することができますorElseThrow()
メソッドが例外をスローします。
これは、指定されたオブジェクトが存在しないのREST APIで使用することができます。あなたは、この方法は、例えば、カスタム例外をスローし使用することができますResourceNotFound()
よう:
@GetMapping("/employees/{id}")
public User getEmployee(@PathVariable("id") String id) {
return employeeRepository.findById(id).orElseThrow(() -> new ResourceNotFoundException("Employee not found with id " + id););
}
复制代码
値をフィルタリングするフィルタ()メソッドの任意の使用
あなたがオブジェクトオプションの従業員を持っていると仮定します。さて、あなたはセックスワーカーと機能に対応する呼び出しをチェックしています。
ここでこれを行うための古い方法は次のとおりです。
if(employee != null && employee.getGender().equalsIgnoreCase("MALE")) {
// 调用函数
}
复制代码
さて、あなたはオプションを使用することができますどのように見てみましょうfilter()
これを達成する方法を:
optional.filter(user -> employee.getGender().equalsIgnoreCase("MALE")) .ifPresent(() -> {
// 你的函数
})
复制代码
filter()
パラメータとして述語関数法。オブジェクトが非ヌル値と一致する述語提供された値が含まれている場合、オプションは、この方法は、オプションを含む、対象の値を返します。
それ以外の場合、このメソッドはnull値を含む任意のオブジェクトを返します。
地図()抽出及び変換値を用いて
私たちは、従業員の住所を抽出したいシナリオを持っていると仮定するだけでなく、条件を指定したアドレスをプリントアウトします。
次の例を考えてみます。
私たちは、Employee
クラスの持つgetAddress()
メソッドを:
Address getAddress() {
return this.address;
}
复制代码
以下は、これらの要件を達成するための一般的な方法です。
if (employee != null) {
Address address = employee.getAddress();
if (address != null && address.getCountry().equalsIgnoreCase("USA")) {
System.out.println("Employee belongs to USA");
}
}
复制代码
今すぐオプションを使用する方法を見てmap()
、同じ機能を実現するための方法を:
userOptional.map(Employee::getAddress).filter(address -> address.getCountry().equalsIgnoreCase("USA")).ifPresent(() -> {
System.out.println("Employee belongs to USA");
});
复制代码
以前の方法であって、上記のコードが読み取り可能な、簡潔かつ効率と比較しました。
私たちは、より詳細にコードを分析してみましょう:
// 使用map()方法提取地址
Optional<Address> addressOptional = employeeOptional.map(Employee::getAddress)
// 过滤出来自USA的员工
Optional<Address> usaAddressOptional = addressOptional.filter(address -> address.getCountry().equalsIgnoreCase("USA"));
// 如果员工来自USA则输出一些信息
usaAddressOptional.ifPresent(() -> {
System.out.println("Employee belongs to USA");
});
复制代码
上記のコードでは、いずれの場合も以下、メソッドmap()
戻り値を含む任意のオブジェクトをヌル。
- 場合は
employeeOptional
、従業員は存在しません。 - 従業員が存在するが、この方法の場合
getAddress()
はNULLを返します。
それ以外の場合は、リターンアドレスは、従業員の含まれOptional<Address>
たオブジェクトを。
使用flatMap()オプションのカスケード
今、私たちは、上記再検討してみましょうmap()
例に関連する方法。
あなたが見ることができるよう、従業員アドレスがヌルにすることができたとしても、我々はオプション<アドレス>を使用していないgetAddress()
メソッドの戻り値の型を。
場合はgetAddres()
、戻り値の型は、オプションの<アドレス>で、次のような問題は、このコード行で発生します:
Optional<Address> addressOptional = employeeOptional.map(Employee::getAddress)
复制代码
以来getAddress()
メソッドが返すオプションの<アドレス>、したがって、employeeOptional.map()
戻り値の型Optional<Optional<Address>>
。
ここでは、このような状況のためのデモは次のとおりです。
Optional<Optional<Address>> addressOptional = employeeOptional.map(Employee::getAddress)
复制代码
この場合、我々はオプションを入れ子になったが、我々は今、我々が使用することができ、それを行うにはしたくないflatMap()
、この問題に対する解決策を:
Optional<Address> addressOptional = employeeOptional.flatMap(Employee::getAddress)
复制代码
あなたのパスにする場合ことに注意してください
map()
オブジェクト関数にオプションの方法を返す、あなたが使用する必要があるflatMap()
メソッドを置き換えるmap()
拡張後の結果を得るための方法を。
概要
私たちはオプション8ジャワ、その利点で学んだ、とJavaでオプションを使用して問題を解決してきました。また、いくつかの例を通じて、私たちはより良いJavaの8オプションクラスでいくつかの方法を理解することができます。
読んでくれてありがとう!