ホームページ Java &#&チュートリアル Java8を使用するための正しい姿勢(オプション)

Java8を使用するための正しい姿勢(オプション)

Jan 18, 2017 pm 03:24 PM

Java プログラミング言語

java は、クロスプラットフォームのアプリケーション ソフトウェアを作成できるオブジェクト指向プログラミング言語です。これは、1995 年 5 月に Sun Microsystems によって開始された Java プログラミング言語および Java プラットフォームです (つまり、JavaEE (j2ee)、一般名)。 JavaME(j2me)、JavaSE(j2se))。


Java 8 にはいくつかの非常に便利な API が追加されていることはわかっていますが、その 1 つはオプションです。少し詳しく調べなければ、NullPointException 問題をエレガントに解決できるだろうと軽く考えて、コードを開始します。このように書くと

Optional<User> user = ……
if (user.isPresent()) {
return user.getOrders();
} else {
return Collections.emptyList();
}
ログイン後にコピー

そして、私たちの考え方は依然として同じところにあると言わなければなりませんが、これは本質的には User インスタンスの単なるラッパーであると考えます

User user = …..
if (user != null) {
return user.getOrders();
} else {
return Collections.emptyList();
}
ログイン後にコピー

これが私たちが話そうとしていることです。 Java 8 Optional タイプの正しい姿勢を使用してください。

リオオリンピック中、ニュースでは五つ星の赤旗に問題があると繰り返し取り上げられていましたが、私はそれができませんでした。どう考えても問題はありませんが、中央の小さな星を崇拝する姿勢は間違っていることがわかりました。つまり、Java 8 で Optional に切り替える場合、以前に null を扱ったときと同じ考え方を継承することはできません。Java 8 Optional を使用するための新しい正しい姿勢をマスターする必要があります。率直に言って、次のような方法で Optional を使用しているときは、自分自身でチェックを開始する必要があります

isPresent() メソッドを呼び出すとき

get() メソッドを呼び出すとき

Optional 型がクラスとして使用されているとき/instance 属性

Optional 型がメソッドのパラメータとして使用される場合

isPresent() は obj != null と何の違いもありませんが、isPresent() を使用せずに get() を呼び出すと、私たちの生活は依然として衝撃的になります。 IntelliJ IDEA で警告を受け取る

Reports calls to java.util.Optional.get() without first checking with a isPresent() 
call if a value is available. If the Optional does not contain a value, get() will throw an exception. 
(调用 Optional.get() 前不事先用 isPresent() 检查值是否可用. 假如 Optional 不包含一个值, get() 将会抛出一个异常)
ログイン後にコピー

IntelliJ IDEA では、属性またはメソッドのパラメーターとして Optional 型を使用することは強く推奨されません

Reports any uses of java.util.Optional<T>, java.util.OptionalDouble, java.util.OptionalInt, 
java.util.OptionalLong or com.google.common.base.Optional as the type for a field or a parameter. Optional was designed
 to provide a limited mechanism for library method return types where there needed to be a clear way to represent 
 “no result”. Using a field with type java.util.Optional is also problematic if the class needs to be Serializable, 
 which java.util.Optional is not. (使用任何像 Optional 的类型作为字段或方法参数都是不可取的. Optional 只设计为类库方法的,
  可明确表示可能无值情况下的返回类型. Optional 类型不可被序列化, 用作字段类型会出问题的)
ログイン後にコピー

したがって、Optional では、実際に信頼できるのは、isPresent() と get() 以外の他のメソッドである必要があります:

public Optional map(Function マッパー)

public T orElse(T other )

public T orElseGet(Supplier other)

public void ifPresent(Consumer Consumer)

public Optional predicate public flatMap(Function ; マッパー)

public T orElseThrow(SupplierExceptionSupplier) throws

まず最初に、3 つの構造について触れなければなりません。 Optional のメソッド: Optional.of(obj)、Optional.ofNullable(obj)、およびクリア Optional.empty ()

Optional.of(obj): 受信した obj が null 値であってはいけないことが必要です。そうでない場合は、ロールに入る前に NullPointerException

Optional.ofNullable(obj): Optional インスタンスを構築するためのスマートで寛容な方法が必要です。null を渡すと、Optional.empty() が返されます。は null ではないので、Optional.of(obj) を呼び出します。

つまり、Optional を使用するだけでよいということですか? .ofNullable(obj) は一度だけ使用でき、次の方法で Optional インスタンスを構築するだけで十分です。は変更されず、2 番目の変更に適応しますか? それは必ずしも当てはまりません。そうでない場合、なぜ Optional.of(obj) がそれほど公開される必要があるのでしょうか?

私の個人的な意見は次のとおりです: 1. Optional.of(obj) に渡される obj パラメータを null にすることはできません。たとえば、それが新しく作成されたオブジェクト (Optional.of(new User(...))) である場合、またはオブジェクトが非-null 定数 2. obj が null ではないことを主張したい場合、つまり、obj が null の場合は、null ポインタ例外を非表示にするのではなく、すぐに NullPointException 例外を報告して変更したい場合は、決定的である必要があります。 Optional.of(obj) を使用して、Optional に隠れる機会を予測できない null 値に利用させずに、Optional インスタンスを構築します。

ここで、既存の Optional インスタンスの使用を開始します。オプションの ユーザー。if(user.isPresent()) { ... } else { ... }

存在する場合は返されます。存在しない場合は、デフォルト値

return user.orElse(null);  //而不是 return user.isPresent() ? user.get() : null;
return user.orElse(UNKNOWN_USER);
ログイン後にコピー

が存在する場合は返され、そうでない場合は関数によって生成されます

return user.orElseGet(() -> fetchAUserFromDatabase()); //而不要 return user.isPresent() ? user: fetchAUserFromDatabase();
ログイン後にコピー

存在才对它做点什么

user.ifPresent(System.out::println);

//而不要下边那样
if (user.isPresent()) {
  System.out.println(user.get());
}
ログイン後にコピー

map 函数隆重登场

当 user.isPresent() 为真, 获得它关联的 orders, 为假则返回一个空集合时, 我们用上面的 orElse, orElseGet 方法都乏力时, 那原本就是 map 函数的责任, 我们可以这样一行

return user.map(u -> u.getOrders()).orElse(Collections.emptyList())

//上面避免了我们类似 Java 8 之前的做法
if(user.isPresent()) {
  return user.get().getOrders();
} else {
  return Collections.emptyList();
}
ログイン後にコピー

map 是可能无限级联的, 比如再深一层, 获得用户名的大写形式

return user.map(u -> u.getUsername())
           .map(name -> name.toUpperCase())
           .orElse(null);
ログイン後にコピー

这要搁在以前, 每一级调用的展开都需要放一个 null 值的判断

User user = .....
if(user != null) {
  String name = user.getUsername();
  if(name != null) {
    return name.toUpperCase();
  } else {
    return null;
  }
} else {
  return null;
}
ログイン後にコピー

针对这方面 Groovy 提供了一种安全的属性/方法访问操作符 ?.

user?.getUsername()?.toUpperCase();
ログイン後にコピー

Swift 也有类似的语法, 只作用在  Optional 的类型上.

用了 isPresent() 处理 NullPointerException 不叫优雅, 有了  orElse, orElseGet 等, 特别是 map 方法才叫优雅.

其他几个, filter() 把不符合条件的值变为 empty(),  flatMap() 总是与 map() 方法成对的,  orElseThrow() 在有值时直接返回, 无值时抛出想要的异常.

一句话小结: 使用 Optional 时尽量不直接调用 Optional.get() 方法, Optional.isPresent() 更应该被视为一个私有方法, 应依赖于其他像 Optional.orElse(), Optional.orElseGet(), Optional.map() 等这样的方法.

最后, 最好的理解 Java 8 Optional 的方法莫过于看它的源代码 java.util.Optional, 阅读了源代码才能真真正正的让你解释起来最有底气, Optional 的方法中基本都是内部调用  isPresent() 判断, 真时处理值, 假时什么也不做.

以上就是使用 Java8 Optional 的正确姿势的内容,更多相关内容请关注PHP中文网(www.php.cn)!


このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Java 8で1年前または1年後の日付を計算するにはどうすればよいですか? Java 8で1年前または1年後の日付を計算するにはどうすればよいですか? Apr 26, 2023 am 09:22 AM

Java8 は、minus() メソッドを使用して 1 年前の日付または 1 年後の日付を計算し、1 年前の日付を計算します。 packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo09{publicstaticvoidmain(String[ ]args ){LocalDatetoday=LocalDate.now();LocalDateprevious Year=today.minus(1,ChronoUni

Java で一般的に使用される Optional メソッドは何ですか? Java で一般的に使用される Optional メソッドは何ですか? May 09, 2023 am 11:34 AM

はじめに Java のオプションはコンテナ オブジェクトであり、null 以外の値を含めることも、空にすることもできます。その主な目的は、コードを記述するときに null ポインター例外を回避することです。 1. Optional オブジェクトの作成 of() メソッドを使用して、null 以外の値を含む Optional オブジェクトを作成できます (例: Optionaloptional=Optional.of("value"))。 ; ofNullable() メソッドを通じて作成することもできます。null 値を含む可能性のある Optional オブジェクト (例: Optionaloptional=Optiona)

Java 8を使用して1週間後の日付を計算するにはどうすればよいですか? Java 8を使用して1週間後の日付を計算するにはどうすればよいですか? Apr 21, 2023 pm 11:01 PM

Java8 で 1 週間後の日付を計算する方法 この例では、1 週間後の日付を計算します。 LocalDate 日付には時間情報が含まれません。その plus() メソッドは、日、週、月を追加するために使用されます。これらの時間単位は ChronoUnit クラスで宣言されます。 LocalDate も不変型なので、戻った後に変数を使用して値を割り当てる必要があります。 packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo08{publicstaticvoidmain(String[

Java8でClockクラスを使用する方法 Java8でClockクラスを使用する方法 Apr 25, 2023 pm 03:37 PM

Java8 の Clock クラス Java8 では、現在のタイムスタンプ、つまり現在のタイムゾーンの日付と時刻の情報を取得するための Clock クラスが追加されています。以前に System.currentTimeInMillis() と TimeZone.getDefault() が使用されていた場合は、Clock に置き換えることができます。 packagecom.shxt.demo02;importjava.time.Clock;publicclassDemo10{publicstaticvoidmain(String[]args){//現在のタイムベースを返します

Javaのオプション関数を使用してnull値の場合を処理する方法 Javaのオプション関数を使用してnull値の場合を処理する方法 Oct 20, 2023 am 10:06 AM

Java で Optional 関数を使用して null 値を処理する方法 Java プログラミングでは、null 値を処理する場面によく遭遇します。 Null ポインター例外はよくあるエラーですが、この状況を回避するために、Java8 では null 値の状況を処理する Optional クラスが導入されました。 Optional クラスは、空でない値を含めることができる、または値を含めないコンテナー クラスです。 Optional クラスを使用すると、null 値の状況をより適切に処理し、null ポインター例外を回避できます。下

Java8でタイムゾーンを扱う方法 Java8でタイムゾーンを扱う方法 Apr 27, 2023 pm 09:22 PM

Java 8 でのタイムゾーンの処理 Java 8 では、日付と時刻を分離するだけでなく、タイムゾーンも分離します。特定のタイム ゾーンを処理する ZoneId や、特定のタイム ゾーンの時間を表す ZoneDateTime など、一連の個別のクラスが追加されました。これは、Java8 より前の GregorianCalendar クラスによって行われていました。次の例は、このタイム ゾーンの時刻を別のタイム ゾーンの時刻に変換する方法を示しています。 packagecom.shxt.demo02;importjava.time.LocalDateTime;importjava.time.ZoneId;importjava.time.ZonedDateT

Java8で現在のタイムスタンプを取得する方法 Java8で現在のタイムスタンプを取得する方法 May 01, 2023 am 11:46 AM

Java8 で現在のタイムスタンプを取得します。Instant クラスには、次に示すように、現在のタイムスタンプを返す静的ファクトリ メソッド now() があります。 Instanttimestamp=Instant.now();System.out.println("このインスタントの値は何ですか"+timestamp.t

Java8 で事前定義された書式設定ツールを使用して日付を解析または書式設定する方法 Java8 で事前定義された書式設定ツールを使用して日付を解析または書式設定する方法 Apr 28, 2023 pm 07:40 PM

事前定義された書式設定ツールを使用して Java8 で日付を解析または書式設定する方法 packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.format.DateTimeFormatter;publicclassDemo17{publicstaticvoidmain(String[]args){StringdayAfterTommorrow="20180205 ";LocalDateformatted =LocalDate.parse

See all articles