特定のインスタンスのインスタンスメソッド参照
特定のオブジェクトを保持し、そのインスタンスメソッドの1つをコールバックやリスナー用に参照します。
「特定のインスタンスのインスタンスメソッド参照」はCoddyKit上の無料Java Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJava Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Java Academyコースには全4レッスンが含まれています。
特定のインスタンスへの参照
特定のインスタンスに対するインスタンスメソッド参照は、特定のオブジェクトを保持し、そのオブジェクトのメソッドを参照します。構文: instance::methodName。
// System.out is a specific PrintStream instance
List<String> names = List.of("Alice","Bob","Carol");
names.forEach(System.out::println); // System.out is the captured instanceカスタムオブジェクトのインスタンスの保持
任意のオブジェクトを保持できます。メソッド参照は、作成時点のインスタンスを使用します:
class Greeter {
private String prefix;
Greeter(String prefix) { this.prefix = prefix; }
String greet(String name) { return prefix + ", " + name + "!"; }
}
Greeter g = new Greeter("Hello");
java.util.function.Function<String, String> greetFn = g::greet;
System.out.println(greetFn.apply("Alice")); // Hello, Alice!
System.out.println(greetFn.apply("Bob")); // Hello, Bob!Supplierとしての使用
特定のオブジェクトに結び付けられた引数なしのインスタンスメソッドは、Supplier<T>に一致します:
StringBuilder sb = new StringBuilder("Hello World");
java.util.function.Supplier<String> toString = sb::toString;
System.out.println(toString.get()); // Hello World
sb.append(" !");
System.out.println(toString.get()); // Hello World ! (sb is live)Predicateとしての使用
特定のインスタンスに結び付けられたbooleanを返すインスタンスメソッドは、Predicateに一致します:
String prefix = "Java";
java.util.function.Predicate<String> startsWith = prefix::equals;
// Hmm, this checks if prefix.equals(candidate).
// More useful:
Predicate<String> startsWithJ = s -> s.startsWith("J");
// But a specific instance Predicate:
StringBuilder pattern = new StringBuilder("hello");
Predicate<String> equalsHello = ((CharSequence)"hello")::equals;
System.out.println(equalsHello.test("hello")); // true
System.out.println(equalsHello.test("world")); // falseリスナー / コールバックパターン
特定のインスタンスへのメソッド参照は、イベントリスナーやコールバックに最適です。ハンドラーオブジェクトを自然に保持できます:
class EventHandler {
void onEvent(String event) {
System.out.println("Handling: " + event);
}
}
EventHandler handler = new EventHandler();
List<String> events = List.of("click","hover","submit");
events.forEach(handler::onEvent); // captures the specific handler instance実践:クラスにバインドされた Logger
Consumer として使用するために、Logger を特定の Logger インスタンスにバインドします:
import java.util.logging.*;
Logger log = Logger.getLogger("MyApp");
List<String> messages = List.of("Starting","Processing","Done");
messages.stream()
.map(String::toUpperCase)
.forEach(log::info); // log is the specific Logger instance参照はバインド時に状態をキャプチャする
参照を通して確認できるオブジェクトの現在の状態は、参照作成時のスナップショットではなく、オブジェクトのライブな状態を反映します:
List<String> list = new ArrayList<>(List.of("A","B"));
java.util.function.Supplier<Integer> sizeRef = list::size;
System.out.println(sizeRef.get()); // 2
list.add("C");
System.out.println(sizeRef.get()); // 3 (reflects live state)特定インスタンスと任意インスタンスの比較
2 種類の異なるメソッド参照は似て見えますが、その違いを理解しておきましょう:
// Specific instance: s is captured at binding
String s = "hello";
Predicate<String> p1 = s::equalsIgnoreCase; // String::equalsIgnoreCase bound to 'hello'
// Arbitrary instance: receiver is the stream element
Function<String, String> p2 = String::toUpperCase; // receiver IS the elementユースケース:スレッドセーフなメソッド委譲
サービスオブジェクトの synchronized メソッドを関数型インターフェースとしてバインドし、安全に非同期で使用します:
class Counter {
private int count = 0;
synchronized void increment(String ignored) { count++; }
int get() { return count; }
}
Counter c = new Counter();
List<String> tasks = List.of("t1","t2","t3");
tasks.forEach(c::increment);
System.out.println(c.get()); // 3キャプチャしたインスタンスが null の場合
メソッド参照の作成時にキャプチャしたオブジェクトが null の場合、NullPointerException はバインド時ではなく呼び出し時にスローされます:
StringBuilder sb = null;
// Reference is created without error:
java.util.function.Supplier<String> ref = sb::toString;
try {
ref.get(); // NPE thrown here
} catch (NullPointerException e) {
System.out.println("NPE at invocation");
}比較のまとめ
3 種類のメソッド参照を比較します:
- ClassName::staticMethod — static で、レシーバーなし
- instance::instanceMethod — 特定のオブジェクトにバインド
- ClassName::instanceMethod — レシーバーはストリーム要素(任意インスタンス)
クイックチェック
EventHandler h = new EventHandler(); list.forEach(h::handle); の場合、各要素に対する handle 呼び出しのレシーバーは何でしょうか?
復習:特定インスタンスのメソッド参照
重要なポイント:
- 構文:instance::methodName — 特定のオブジェクトをキャプチャします
- キャプチャしたオブジェクトが、すべての呼び出しでレシーバーになります
- コールバック、リスナー、ロギングのパターンに適しています
- 参照を通して、キャプチャしたインスタンスのライブな状態を確認できます
- インスタンスが null の場合、NPE はバインド時ではなく呼び出し時に発生します
よくある質問
「特定のインスタンスのインスタンスメソッド参照」レッスンは無料ですか?
はい。「特定のインスタンスのインスタンスメソッド参照」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Java Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Java Academyコースには全4レッスンが含まれています。
「特定のインスタンスのインスタンスメソッド参照」で何を学びますか?
特定のオブジェクトを保持し、そのインスタンスメソッドの1つをコールバックやリスナー用に参照します。 ブラウザで直接実行するハンズオンコードでJava Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Java Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJava Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「特定のインスタンスのインスタンスメソッド参照」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJava Academyレッスンでコードを書いて実行できますか?
はい。すべてのJava Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- static メソッド参照
- 特定のインスタンスのインスタンスメソッド参照
- 任意のインスタンスメソッド参照
- コンストラクター参照