ここでの多くの回答は::
動作をよく説明しているので::
、インスタンス変数に使用する場合、演算子は参照する機能インターフェースとまったく同じシグネチャを持つ必要がないことを明確にしたいと思います。TestObject型のBinaryOperatorが必要だとしましょう。従来の方法では、次のように実装されています。
BinaryOperator<TestObject> binary = new BinaryOperator<TestObject>() {
@Override
public TestObject apply(TestObject t, TestObject u) {
return t;
}
};
匿名実装でわかるように、2つのTestObject引数が必要で、TestObjectオブジェクトも返されます。::
演算子を使用してこの条件を満たすには、静的メソッドから始めることができます。
public class TestObject {
public static final TestObject testStatic(TestObject t, TestObject t2){
return t;
}
}
次に呼び出す:
BinaryOperator<TestObject> binary = TestObject::testStatic;
うまくコンパイルされました。インスタンスメソッドが必要な場合はどうでしょうか。インスタンスメソッドでTestObjectを更新しましょう:
public class TestObject {
public final TestObject testInstance(TestObject t, TestObject t2){
return t;
}
public static final TestObject testStatic(TestObject t, TestObject t2){
return t;
}
}
これで、次のようにインスタンスにアクセスできます。
TestObject testObject = new TestObject();
BinaryOperator<TestObject> binary = testObject::testInstance;
このコードは正常にコンパイルされますが、以下のコードではコンパイルできません。
BinaryOperator<TestObject> binary = TestObject::testInstance;
私の日食は「タイプTestObjectから非静的メソッドtestInstance(TestObject、TestObject)への静的参照を作成できません...」
十分に公平なインスタンスメソッドですが、testInstance
以下のようにオーバーロードすると:
public class TestObject {
public final TestObject testInstance(TestObject t){
return t;
}
public final TestObject testInstance(TestObject t, TestObject t2){
return t;
}
public static final TestObject testStatic(TestObject t, TestObject t2){
return t;
}
}
そして呼び出す:
BinaryOperator<TestObject> binary = TestObject::testInstance;
コードは正常にコンパイルされます。それはtestInstance
二重の代わりに単一のパラメーターで呼び出すからです。では、2つのパラメータはどうなりましたか?印刷して見てみましょう:
public class TestObject {
public TestObject() {
System.out.println(this.hashCode());
}
public final TestObject testInstance(TestObject t){
System.out.println("Test instance called. this.hashCode:"
+ this.hashCode());
System.out.println("Given parameter hashCode:" + t.hashCode());
return t;
}
public final TestObject testInstance(TestObject t, TestObject t2){
return t;
}
public static final TestObject testStatic(TestObject t, TestObject t2){
return t;
}
}
どちらが出力されます:
1418481495
303563356
Test instance called. this.hashCode:1418481495
Given parameter hashCode:303563356
JVMはparam1.testInstance(param2)を呼び出すのに十分スマートです。testInstance
TestObjectではなく、別のリソースから使用できますか?
public class TestUtil {
public final TestObject testInstance(TestObject t){
return t;
}
}
そして呼び出す:
BinaryOperator<TestObject> binary = TestUtil::testInstance;
それはコンパイルせず、コンパイラーは「タイプTestUtilはtestInstance(TestObject、TestObject)を定義しません」と通知します。そのため、コンパイラは、同じ型でない場合に静的参照を探します。多態性についてはどうですか?最終修飾子を削除してSubTestObjectクラスを追加すると、次のようになります。
public class SubTestObject extends TestObject {
public final TestObject testInstance(TestObject t){
return t;
}
}
そして呼び出す:
BinaryOperator<TestObject> binary = SubTestObject::testInstance;
コンパイルも行われず、コンパイラは静的参照を探します。しかし、以下のコードはis-aテストに合格しているため、正常にコンパイルされます。
public class TestObject {
public SubTestObject testInstance(Object t){
return (SubTestObject) t;
}
}
BinaryOperator<TestObject> binary = TestObject::testInstance;
*ただ勉強しているだけなので、試してみてわかりました。間違っていた場合は、遠慮なく修正してください。