要約: Optional は null キーワードの代替ではありませんが、null 判定のより洗練された実装を提供します
NullPointException は、Java が最初から設計されていないにもかかわらず、すべての Java プログラマーが遭遇する例外であると言えます。私たちはプログラマをポインタの苦痛から解放しようとしましたが、ポインタは実際に存在し、Java 設計者は Java 言語でポインタをよりシンプルで使いやすくすることしかできませんが、ポインタを完全に排除することはできません。そのため、キーワード
null
があるのです。私たちが毎日目にしているもの。
Null ポインター例外は実行時例外です。明確な処理戦略がない場合、ベスト プラクティスはプログラムを早期にハングアップさせることです。ただし、多くのシナリオでは、開発者はそうしません。特定の処理戦略はありませんが、null ポインター例外の存在をまったく認識しません。例外が発生した場合の処理戦略も、例外が存在する箇所に if ステートメントの判定を追加するだけで十分です。ただし、このような応答戦略では、プログラム内でより多くの null 判定が発生することになります。コード内の null キーワードの出現を最小限に抑える必要があり、java8 によって提供される
Optional
クラスは、NullPointException を減らすだけでなく、コードの美しさを向上させます。ただし、最初に、これは
null
return 0;
}
return str.length();
Optional クラスを使用する場合、実装は次のようになります:
return Optional.ofNullable(str).map(String: :length).orElse(0);
Optional コードは比較的簡潔ですが、コード量が多いとnull判定を忘れてしまいがちですが、Optionalクラスを使うことでそのような問題を回避できます。
2. 基本的な使用方法
str.length()
empty()
オプションは、空でないオブジェクトを作成するためのメソッド
Optional<String>
of()
オブジェクトを作成します: 空であることが許可されます
渡されたパラメータは null 値の可能性があるため、Optional の
NullPointException
デモンストレーションのために、次のような
ofNullable()
User
マッピング: マップと flatMap
マッピングは、入力を別の形式の出力に変換する操作です。たとえば、前の例では、文字列を入力し、その文字列の長さを出力します。シュート、これを達成するために
/** * @author: zhenchao.Wang 2016-9-24 15:36:56 */ public class User { /** 用户编号 */ private long id; private String name; private int age; private Optionalphone; private Optional<String> email; public User(String name, int age) { this.name = name; this.age = age; } // 省略setter和getter }
メソッドを使用します。人の名前を取得したいとすると、次のように実装できます:
String name = Optional.ofNullable(user).map(User::getName).orElse("no name");このように、入力パラメータ user が空でない場合、その名前が返され、それ以外の場合は
map()
long Phone = optUser. flatMap(User::getPhone).orElse(-1L);
flapMap は各ストリームをフラット化できますストリームになるメソッドによって返されます。これについては、ストリーミング処理に特化した次の記事で詳しく説明します。
フィルター: filterer
filter は、名前が示すように、18 歳以上の成人をフィルターする目的を達成するためにフィルター操作をパラメーターとしてこのメソッドに渡すことができます。 3. デフォルトの動作
デフォルトの動作は、上記の例で使用したような条件を満たさない場合に実行される操作です
orElse()
就是一个默认操作,用于在Optional对象为空时执行特定操作,当然也有一些默认操作是当满足条件的对象存在时执行的操作。
get()
get用于获取变量的值,但是当变量不存在时则会抛出
NoSuchElementException
,所以如果不确定变量是否存在,则不建议使用
orElse(T other)
当Optional的变量不满足给定条件时,则执行orElse,比如前面当str为null时,返回0。
orElseGet(Supplier<? extends X> expectionSupplier)
如果条件不成立时,需要执行相对复杂的逻辑,而不是简单的返回操作,则可以使用orElseGet实现:
long phone = optUser.map(User::getPhone).map(Optional::get).orElseGet(() -> { // do something here return -1L; }); orElseThrow(Supplier<? extends X> expectionSupplier)
与get()方法类似,都是在不满足条件时返回异常,不过这里我们可以指定返回的异常类型。
ifPresent(Consumer super T>)
当满足条件时执行传入的参数化操作。
Optional是一个final类,未实现任何接口,所以当我们在利用该类包装定义类的属性的时候,如果我们定义的类有序列化的需求,那么因为Optional没有实现Serializable接口,这个时候执行序列化操作就会有问题:
public class User implements Serializable{ /** 用户编号 */ private long id; private String name; private int age; private Optionalphone; // 不能序列化 private Optional<String> email; // 不能序列化
不过我们可以采用如下替换策略:
private long phone; public Optional<Long> getPhone() { return Optional.ofNullable(this.phone); }
看来Optional在设计的时候就没有考虑将它作为类的字段使用~
以上就是Java8 新特性之 Optional 类 的内容,更多相关内容请关注PHP中文网(www.php.cn)!