クラスメソッドのメソッド参照は次のように記述する。
クラス名::メソッド名
次のプログラムで考える。
public class MethodReferenceDemo {
@FunctionalInterface
interface Funcion<T> {
void apply(T value);
}
static void print(String text) {
System.out.println(text);
}
public static void main(String... args) {
Funcion<String> func = text -> MethodReferenceDemo.print(text);
func.apply(Hello, World!);
}
}
このような場合、ラムダ式をメソッド参照で置き換えることがでる。
Funcion func = MethodReferenceDemo::print;
関数型インタフェースのメソッドの引数が複数の場合、関数型インタフェースのメソッドの引数の並びとクラスメソッドの引数の並びが同一でなければならない。
public class MethodReferenceDemo {
@FunctionalInterface
interface TwoArgFuncion {
void apply(double x, int y);
}
static void printPower1(double x, int y) {
double power = 1;
for (int i = 0; i < y; i++) {
power *= x;
}
System.out.println(power);
}
static void printPower2(int y, double x) {
double power = 1;
for (int i = 0; i < y; i++) {
power *= x;
}
System.out.println(power);
}
public static void main(String... args) {
// OK 引数の並びが同一
TwoArgFuncion func1 = MethodReferenceDemo::printPower1;
// NG 引数の並びが異なる
TwoArgFuncion func2 = MethodReferenceDemo::printPower2;
func1.apply(10.0, 2);
func2.apply(10.0, 2);
}
}
クラスメソッドがオーバーロードされている場合も、関数型インタフェースのメソッドと引数が一致するクラスメソッドが選択される。
次のコードは実行するとdouble: 10.0 int: 2と出力される。
public class MethodReferenceDemo {
@FunctionalInterface
interface TwoArgFuncion {
void apply(double x, int y);
}
static void print(double x, int y) {
System.out.println(double: + x + int: + y);
}
static void print(int y, double x) {
System.out.println(int: + y + double: + x);
}
public static void main(String... args) {
// 引数がdouble, intのprintメソッドが選択される
TwoArgFuncion func = MethodReferenceDemo::print;
func.apply(10.0, 2);
}
}