Apakah ada cara untuk melewatkan fungsi panggilan balik dalam metode Java?
Perilaku yang saya coba tiru adalah Delegasi .Net diteruskan ke suatu fungsi.
Saya telah melihat orang-orang menyarankan untuk membuat objek terpisah tetapi itu tampaknya berlebihan, namun saya sadar bahwa kadang-kadang berlebihan adalah satu-satunya cara untuk melakukan sesuatu.
java
callback
function-pointers
Omar Kooheji
sumber
sumber
Jawaban:
Jika Anda bermaksud sesuatu seperti delegasi .NET anonim, saya pikir kelas anonim Java dapat digunakan juga.
sumber
Sejak Java 8, ada lambda dan referensi metode:
Misalnya, jika Anda menginginkan antarmuka fungsional
A -> B
seperti:maka Anda bisa menyebutnya seperti itu
Anda juga dapat melewati metode kelas. Katakanlah Anda memiliki:
Maka Anda dapat melakukan:
Catatan :
Di sini saya menggunakan antarmuka fungsional
Function<A,B>
, tetapi ada banyak lainnya dalam paketjava.util.function
. Yang paling terkenal adalahSupplier
:void -> A
Consumer
:A -> void
BiConsumer
:(A,B) -> void
Function
:A -> B
BiFunction
:(A,B) -> C
dan banyak lainnya yang berspesialisasi pada beberapa tipe input / output. Kemudian, jika tidak menyediakan yang Anda butuhkan, Anda dapat membuat antarmuka fungsional Anda sendiri seperti:
Contoh penggunaan:
sumber
java.util.function
adalah yang Anda cari, maka Anda bisa melanjutkan. Kemudian Anda bisa bermain dengan obat generik untuk I / O. (?)java.util.function
tidak cukup.Untuk kesederhanaan, Anda dapat menggunakan Runnable :
Pemakaian:
sumber
public interface SimpleCallback { void callback(Object... objects); }
Ini cukup mudah dan bisa berguna Anda harus melewati beberapa params juga.Sedikit nitpicking:
Melewati panggilan balik termasuk membuat objek terpisah dalam hampir semua bahasa OO, sehingga hampir tidak dapat dianggap berlebihan. Apa yang mungkin Anda maksudkan adalah bahwa di Jawa, itu mengharuskan Anda untuk membuat kelas terpisah, yang lebih bertele-tele (dan lebih banyak sumber daya) daripada dalam bahasa dengan fungsi atau penutup kelas satu yang eksplisit. Namun, kelas anonim setidaknya mengurangi verbositas dan dapat digunakan inline.
sumber
namun saya melihat ada cara yang paling disukai yaitu apa yang saya cari .. pada dasarnya berasal dari jawaban ini tetapi saya harus memanipulasinya untuk lebih mubazir dan efisien .. dan saya pikir semua orang mencari apa yang saya cari.
Ke titik::
pertama buat Antarmuka yang sederhana
sekarang untuk membuat panggilan balik ini berjalan kapan pun Anda ingin lakukan untuk menangani hasil - lebih mungkin setelah panggilan async dan Anda ingin menjalankan beberapa hal yang tergantung pada penggunaan kembali ini
doSomething
adalah fungsi yang membutuhkan waktu Anda ingin menambahkan panggilan balik untuk memberi tahu Anda ketika hasilnya datang, tambahkan antarmuka panggilan balik sebagai parameter untuk metode iniharap poin saya jelas, selamat menikmati;)
sumber
Ini sangat mudah di Jawa 8 dengan lambdas.
sumber
Saya menemukan ide menerapkan menggunakan perpustakaan refleksi menarik dan muncul dengan ini yang saya pikir berfungsi dengan baik. Satu-satunya sisi adalah kehilangan waktu kompilasi memeriksa bahwa Anda melewati parameter yang valid.
Anda menggunakannya seperti ini
sumber
Metode bukanlah (belum) objek kelas satu di Jawa; Anda tidak dapat melewatkan pointer fungsi sebagai panggilan balik. Alih-alih, buat objek (yang biasanya mengimplementasikan antarmuka) yang berisi metode yang Anda butuhkan dan berikan itu.
Proposal untuk penutupan di Jawa — yang akan menyediakan perilaku yang Anda cari — telah dibuat, tetapi tidak ada yang akan disertakan dalam rilis Java 7 mendatang.
sumber
Ketika saya membutuhkan fungsionalitas semacam ini di Jawa, saya biasanya menggunakan pola Observer . Memang menyiratkan objek tambahan, tapi saya pikir ini cara yang bersih untuk pergi, dan merupakan pola yang dipahami secara luas, yang membantu dengan keterbacaan kode.
sumber
Periksa penutupan bagaimana mereka telah diterapkan di perpustakaan lambdaj. Mereka sebenarnya memiliki perilaku yang sangat mirip dengan delegasi C #:
http://code.google.com/p/lambdaj/wiki/Closures
sumber
Saya mencoba menggunakan java.lang.reflect untuk mengimplementasikan 'callback', berikut ini contohnya:
sumber
timer.SetTimer ((int)(Math.random ()*10), System.out, "printf", "%s: [%s]", new Object[]{"null test", null});
. output akannull test: [null]
args[i].getClass()
? Maksud saya adalah itu tidak berfungsi jika Anda memilih metode berdasarkan tipe argumen. Ini berfungsi dengan baikString.format
, tetapi mungkin tidak bekerja dengan hal lain yang menerimanull
.argTypes
array, jadi sekarang kita dapat meneruskannull
argumen / parameter tanpa terjadi NullPointerException. Contoh hasil:NullParameterTest: String parameter=null, int parameter=888
Anda juga dapat melakukan
Callback
menggunakanDelegate
pola:Callback.java
PagerActivity.java
CustomPagerAdapter.java
sumber
Saya baru saja mulai melakukan sesuatu seperti ini:
sumber
ini agak lama, tetapi bagaimanapun ... Saya menemukan jawaban Peter Wilkinson bagus kecuali untuk fakta bahwa itu tidak bekerja untuk tipe primitif seperti int / Integer. Masalahnya adalah
.getClass()
untukparameters[i]
, yang mengembalikan misalnyajava.lang.Integer
, yang di sisi lain tidak akan ditafsirkan dengan benar olehgetMethod(methodName,parameters[])
(kesalahan Java) ...Saya menggabungkannya dengan saran dari Daniel Spiewak ( dalam jawabannya untuk ini ); langkah-langkah menuju sukses termasuk: menangkap
NoSuchMethodException
->getMethods()
-> mencari yang cocok denganmethod.getName()
-> dan kemudian secara eksplisit mengulang daftar parameter dan menerapkan solusi Daniels, seperti mengidentifikasi jenis pencocokan dan pencocokan tanda tangan.sumber
Saya pikir menggunakan kelas abstrak lebih elegan, seperti ini:
sumber
object
untuk "memberitahukan" yang lainobject
ketika sesuatu yang signifikan telah terjadi, sehingga yang keduaobject
dapat menangani acara tersebut. Andaabstract class
tidak pernah terpisahobject
, itu hanya terpisahclass
. Anda hanya menggunakan satuobject
dan menjadi berbedaclasses
untuk melakukan fungsi yang berbeda, yang merupakan inti dari polimorfisme, bukan pola panggilan balik.Pada dasarnya jika Anda ingin membuat objek antarmuka tidak mungkin, karena antarmuka tidak dapat memiliki objek.
Pilihannya adalah membiarkan beberapa kelas mengimplementasikan antarmuka dan kemudian memanggil fungsi itu menggunakan objek kelas itu. Tetapi pendekatan ini benar-benar bertele-tele.
Sebagai alternatif, tulis HelloWorld baru () (* oberserve ini bukan antarmuka bukan kelas) dan kemudian tindak lanjuti dengan definisi metode antarmuka itu sendiri. (* Defination ini pada kenyataannya adalah kelas anonim). Kemudian Anda mendapatkan referensi objek di mana Anda dapat memanggil metode itu sendiri.
sumber
Buat Antarmuka, dan Buat Properti Antarmuka yang Sama di Kelas Callback.
Sekarang di kelas di mana Anda ingin dipanggil kembali mengimplementasikan Interface Dibuat di atas. dan Juga Lulus "ini" Obyek / Referensi kelas Anda untuk dipanggil kembali.
sumber