【Java進化史 第21回 】Java8 〜 ::(メソッド参照)とは何か。どう読めばいいのか〜
若手のコードを見た。
list.forEach(System.out::println);
「:」なら知っている。
でも「::」は知らない。
Javaに、こんな記号あったか?
どこが引数で、どこが処理なのか。
まずは、一度戻る。
■ 昔のJavaに戻る
for (String s : list) {
System.out.println(s);
}
これなら分かる。
■ 次にラムダに戻る
list.forEach(s -> System.out.println(s));
s -> System.out.println(s)
左側が「受け取る引数」。
右側が「実行する処理」。
s を受け取り、println(s) を実行する。
■ 何が省略されたのか
System.out.println(s)
受け取った s を、そのまま println に渡しているだけ。
だから省略できる。
■ ここで :: が出てくる
System.out::println
これは、
s -> System.out.println(s)
を短く書いただけ。
まだ実行していない。
メソッドそのものを渡している。
■ A::B の読み方
A::B
「A の B というメソッドを使う」
A.B() ではない。
呼び出しではなく、 メソッドそのものを渡している。
■ 他のパターンも同じ
① 静的メソッド
list.stream()
.map(s -> Integer.parseInt(s));
↓
list.stream()
.map(Integer::parseInt);
Integer クラスの parseInt メソッドを使う、 という意味。
② 特定オブジェクトのメソッド
Supplier<String> supplier =
() -> user.getName();
↓
Supplier<String> supplier =
user::getName;
user の getName メソッドを使う。
③ コンストラクタ参照
Supplier<List<String>> supplier =
() -> new ArrayList<>();
↓
Supplier<List<String>> supplier =
ArrayList::new;
ArrayList のコンストラクタを使う、 という意味。
これも同じ。
「new を呼び出している」のではなく、
「このコンストラクタを使ってね」と渡している。
■ もう一度まとめる
昔のJava。
for (String s : list) {
System.out.println(s);
}
ラムダ。
list.forEach(s -> System.out.println(s));
メソッド参照。
list.forEach(System.out::println);
意味は同じ。
段階的に省略されているだけ。
■ 何が変わったのか
昔のJavaは、 「全部書け」だった。
Java8からは、 「同じ意味なら短くしていい」に少し進んだ。
:: は、その象徴。
でも中身は昔と変わらない。
0 件のコメント:
コメントを投稿