Karena banyak jawaban di sini menjelaskan ::
perilaku yang baik , saya juga ingin menjelaskan bahwa ::
operator tidak perlu memiliki tanda tangan yang sama persis dengan Fungsional Interface yang merujuk jika digunakan untuk variabel instan . Mari kita asumsikan kita membutuhkan BinaryOperator yang memiliki tipe TestObject . Secara tradisional ini diterapkan seperti ini:
BinaryOperator<TestObject> binary = new BinaryOperator<TestObject>() {
@Override
public TestObject apply(TestObject t, TestObject u) {
return t;
}
};
Seperti yang Anda lihat dalam implementasi anonim itu membutuhkan dua argumen TestObject dan mengembalikan objek TestObject juga. Untuk memenuhi kondisi ini dengan menggunakan ::
operator kita dapat mulai dengan metode statis:
public class TestObject {
public static final TestObject testStatic(TestObject t, TestObject t2){
return t;
}
}
lalu panggil:
BinaryOperator<TestObject> binary = TestObject::testStatic;
Ok itu dikompilasi dengan baik. Bagaimana jika kita membutuhkan metode instan? Mari perbarui TestObject dengan metode instan:
public class TestObject {
public final TestObject testInstance(TestObject t, TestObject t2){
return t;
}
public static final TestObject testStatic(TestObject t, TestObject t2){
return t;
}
}
Sekarang kita dapat mengakses instance seperti di bawah ini:
TestObject testObject = new TestObject();
BinaryOperator<TestObject> binary = testObject::testInstance;
Kode ini dikompilasi dengan baik, tetapi di bawahnya tidak:
BinaryOperator<TestObject> binary = TestObject::testInstance;
Gerhana saya memberi tahu saya "Tidak dapat membuat referensi statis ke metode pengujian non-statisInstance (TestObject, TestObject) dari jenis TestObject ..."
Cukup adil, ini adalah metode instan, tetapi jika kita kelebihan testInstance
seperti di bawah ini:
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;
}
}
Dan telepon:
BinaryOperator<TestObject> binary = TestObject::testInstance;
Kode hanya akan dikompilasi dengan baik. Karena itu akan memanggil testInstance
dengan parameter tunggal alih-alih ganda. Ok jadi apa yang terjadi dua parameter kita? Mari cetak dan lihat:
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;
}
}
Yang akan menghasilkan:
1418481495
303563356
Test instance called. this.hashCode:1418481495
Given parameter hashCode:303563356
Ok jadi JVM cukup pintar untuk memanggil param1.testInstance (param2). Bisakah kita menggunakan testInstance
dari sumber lain tetapi bukan dari TestObject, yaitu:
public class TestUtil {
public final TestObject testInstance(TestObject t){
return t;
}
}
Dan telepon:
BinaryOperator<TestObject> binary = TestUtil::testInstance;
Itu tidak akan dikompilasi dan kompiler akan memberi tahu: "Jenis TestUtil tidak mendefinisikan testInstance (TestObject, TestObject)" . Jadi kompiler akan mencari referensi statis jika bukan tipe yang sama. Ok bagaimana dengan polimorfisme? Jika kami menghapus pengubah akhir dan menambahkan kelas SubTestObject kami :
public class SubTestObject extends TestObject {
public final TestObject testInstance(TestObject t){
return t;
}
}
Dan telepon:
BinaryOperator<TestObject> binary = SubTestObject::testInstance;
Ini tidak akan dikompilasi juga, kompiler akan tetap mencari referensi statis. Tetapi kode di bawah ini akan dikompilasi dengan baik karena ia lulus is-a test:
public class TestObject {
public SubTestObject testInstance(Object t){
return (SubTestObject) t;
}
}
BinaryOperator<TestObject> binary = TestObject::testInstance;
* Saya baru belajar, jadi saya mencari tahu dengan mencoba dan melihat, jangan ragu untuk mengoreksi saya jika saya salah