今度はコンストラクタ参照です。
感覚的には1つ前の記事のメソッド参照では関数型IFの抽象メソッドの実装を特定のメソッドにするように指定していたけど、
特定としてメソッドをコンストラクタも指定できるみたいなイメージでしょうか。
前回同様適当に関数型IFを幾つか用意します。
SampleBeanはSampleFunctionalIF3のmethodA用に用意した専用の戻り値Beanで、SampleBeanExtはそれをextendsしてデフォルトコンストラクタをつくっただけのBeanです。getter、setterは省略してます。
@FunctionalInterface
public interface SampleFunctionalIF<T> {
String methodA(T object);
}
@FunctionalInterface
public interface SampleFunctionalIF2 {
String methodA();
}
@FunctionalInterface
public interface SampleFunctionalIF3 {
SampleBean methodA(String A, String B);
}
public class SampleBean {
private String val1;
private String val2;
}
public class SampleBeanExt extends SampleBean {
SampleBeanExt(String param1, String param2) {
this.setVal1(param1);
this.setVal2(param2);
System.out.println("SampleBeanExtのコンストラクタが呼ばれました");
}
}
で、これらを実行してみているのが下記。
public class ConstructorRef {
public static void main(String[] args) {
// 引数有(String)の場合
// 関数型IFで規定された抽象メソッドmethodAが呼ばれたタイミングでnew String("xyz")が呼ばれている
System.out.println("-----例1-----");
SampleFunctionalIF<String> sample = String::new;
System.out.println(sample.methodA("xyz"));
// 引数なし(String)の場合
// 関数型IFで規定された抽象メソッドmethodAが呼ばれたタイミングでnew String()が呼ばれている
// 空文字になってるからサイズは0
System.out.println("-----例2-----");
SampleFunctionalIF2 sample2 = String::new;
String s2 = sample2.methodA();
System.out.println(s2.length());
// 引数2個の場合
// 関数型IFで規定された抽象メソッドmethodAが呼ばれたタイミングで
// new SampleBeanExt("hello","world")が呼ばれている
System.out.println("-----例3-----");
SampleFunctionalIF3 sample3 = SampleBeanExt::new;
SampleBean bean = sample3.methodA("hello", "world");
System.out.println("1:" + bean.getVal1());
System.out.println("2:" + bean.getVal2());
}
}
で、実行結果
-----例1-----
xyz
-----例2-----
0
-----例3-----
SampleBeanExtのコンストラクタが呼ばれました
1:hello
2:world
メソッド参照をやったあとならなるほどねって思えますね。
しかしこれはあまり使いどころが思い浮かばないぞ。