Saya menemukan istilah baru di Java 8: "antarmuka fungsional". Saya hanya bisa menemukan satu penggunaannya ketika bekerja dengan ekspresi lambda .
Java 8 menyediakan beberapa antarmuka fungsional bawaan dan jika kita ingin mendefinisikan antarmuka fungsional apa pun maka kita dapat memanfaatkan @FunctionalInterface
anotasi tersebut. Ini akan memungkinkan kita untuk mendeklarasikan hanya satu metode di antarmuka.
Sebagai contoh:
@FunctionalInterface
interface MathOperation {
int operation(int a, int b);
}
Seberapa berguna itu di Java 8 selain hanya bekerja dengan ekspresi lambda ?
(Pertanyaan di sini berbeda dari yang saya tanyakan. Pertanyaannya adalah mengapa kita membutuhkan antarmuka fungsional saat bekerja dengan ekspresi lambda. Pertanyaan saya adalah: mengapa penggunaan lain yang dilakukan antarmuka fungsional selain dengan ekspresi lambda?)
Jawaban:
@FunctionalInterface
anotasi berguna untuk memeriksa waktu kompilasi kode Anda. Anda tidak dapat memiliki lebih dari satu metode selain itustatic
,default
dan metode abstrak yang menimpa metode diObject
dalam Anda@FunctionalInterface
atau antarmuka lain yang digunakan sebagai antarmuka fungsional.Tetapi Anda dapat menggunakan lambdas tanpa anotasi ini dan Anda juga dapat mengganti metode tanpa
@Override
anotasi.Dari dokumen
Ini dapat digunakan dalam ekspresi lambda:
Ini tidak dapat digunakan dalam ekspresi lambda:
Tetapi ini akan memberikan kesalahan kompilasi :
sumber
java.lang.Object
dalam antarmuka fungsional.public
metode selainstatic
dandefault
" ...The dokumentasi membuat memang perbedaan antara tujuan
dan use case
yang kata-katanya tidak menghalangi kasus penggunaan lain secara umum. Karena tujuan utamanya adalah untuk menunjukkan antarmuka fungsional , pertanyaan Anda yang sebenarnya bermuara pada "Apakah ada kasus penggunaan lain untuk antarmuka fungsional selain ekspresi lambda dan referensi metode / konstruktor?"
Karena antarmuka fungsional adalah konstruksi bahasa Jawa yang ditentukan oleh Spesifikasi Bahasa Jawa, hanya spesifikasi itu yang dapat menjawab pertanyaan itu:
JLS §9.8. Antarmuka Fungsional :
Jadi Spesifikasi Bahasa Jawa tidak mengatakan sebaliknya, satu-satunya use case yang disebutkan dalam bagian itu adalah membuat instance antarmuka dengan ekspresi referensi metode dan ekspresi lambda. (Ini termasuk referensi konstruktor karena mereka dicatat sebagai salah satu bentuk ekspresi referensi metode dalam spesifikasi).
Jadi dalam satu kalimat, tidak, tidak ada use case lain untuk itu di Java 8.
sumber
public static String generateTaskId()
versus membuatnya lebih "fungsional" orang lain memilih untuk menulisnya sepertipublic class TaskIdSupplier implements Supplier<String>
denganget
metode menggunakan implementasi generasi yang ada. Apakah itu penyalahgunaan antarmuka fungsional, terutama menggunakan kembaliSupplier
dari JDK built-in? PS: Saya tidak bisa menemukan tempat yang lebih baik / tanya jawab untuk menanyakan hal ini. Senang bermigrasi jika Anda bisa menyarankan.TaskIdSupplier
. Sekarang, pertanyaannya adalah mengapa Anda membuat kelas bernama. Ada beberapa skenario di mana jenis nama seperti itu diperlukan, misalnya ketika Anda ingin mendukung menemukan implementasi melaluiServiceLoader
. Tidak ada yang salah dengan membiarkannya menerapkannyaSupplier
. Tetapi ketika Anda tidak membutuhkannya, jangan membuatnya. Ketika Anda hanya membutuhkanSupplier<String>
, itu sudah cukup untuk digunakanDeclaringClass::generateTaskId
dan menghilangkan kebutuhan untuk kelas eksplisit adalah titik fitur bahasa ini.TaskIdSupplier
penerapannya sepadan dengan usaha, tetapi kemudian konsepServiceLoader
benar - benar terlintas di benak saya. Mengalami beberapa pertanyaan selama diskusi ini kami sedang seperti Apa penggunaanSupplier
'spublic
keberadaan ketika salah satu dapat melanjutkan dan mengembangkan antarmuka mereka sendiri? dan Mengapa tidak memilikipublic static Supplier<String> TASK_ID_SUPPLIER = () ->...
konstanta global? . (1/2)variable.genericMethodName(args)
bukanmeaningfulMethodName(args)
. Menggunakan tipe kelas untuk mewakili suatu fungsi, baik melalui ekspresi lambda / metode referensi atau kelas yang dibuat secara manual, hanya kendaraan untuk melewati fungsi sekitar (dengan tidak adanya tipe fungsi sebenarnya di Jawa). Ini hanya boleh dilakukan bila diperlukan.Seperti yang orang lain katakan, antarmuka fungsional adalah antarmuka yang memaparkan satu metode. Mungkin memiliki lebih dari satu metode, tetapi semua yang lain harus memiliki implementasi standar. Alasan itu disebut "antarmuka fungsional" adalah karena ia secara efektif bertindak sebagai fungsi. Karena Anda dapat melewatkan antarmuka sebagai parameter, itu berarti bahwa fungsi sekarang "warga negara kelas satu" seperti dalam bahasa pemrograman fungsional. Ini memiliki banyak manfaat, dan Anda akan melihatnya cukup banyak ketika menggunakan Stream API. Tentu saja, ekspresi lambda adalah penggunaan utama yang jelas bagi mereka.
sumber
Tidak semuanya. Ekspresi Lambda adalah satu-satunya poin dari penjelasan itu.
sumber
@Override
memberi tahu kompiler bahwa Anda bermaksud menulis sesuatu yang "fungsional" (dan mendapatkan kesalahan jika Anda menyelinap).Ekspresi lambda dapat ditugaskan ke jenis antarmuka fungsional, tetapi begitu juga metode referensi, dan kelas anonim.
Satu hal yang menyenangkan tentang antarmuka fungsional tertentu dalam
java.util.function
adalah bahwa mereka dapat disusun untuk membuat fungsi baru (sepertiFunction.andThen
danFunction.compose
,Predicate.and
, dll) karena metode standar berguna yang dikandungnya.sumber
Antarmuka dengan hanya satu metode abstrak disebut Antarmuka Fungsional. Ini tidak wajib untuk menggunakan @FunctionalInterface, tetapi praktik terbaik untuk menggunakannya dengan antarmuka fungsional untuk menghindari penambahan metode tambahan secara tidak sengaja. Jika antarmuka dianotasi dengan anotasi @FunctionalInterface dan kami mencoba untuk memiliki lebih dari satu metode abstrak, ia melempar kesalahan kompiler.
sumber
Antarmuka fungsional:
Contoh 1:
Contoh 2:
Contoh 3:
Anotasi Java8 -
@FunctionalInterface
Aplikasi Antarmuka Fungsional:
Untuk mempelajari antarmuka fungsional, mempelajari metode default pertama di antarmuka, dan setelah mempelajari antarmuka fungsional, akan mudah bagi Anda untuk memahami referensi metode dan ekspresi lambda
sumber
Anda dapat menggunakan lambda di Java 8
Untuk info lebih lanjut tentang Java Lambdas dan FunctionalInterfaces
sumber
@FunctionalInterface
adalah anotasi baru yang dirilis dengan Java 8 dan memberikan tipe target untuk ekspresi lambda dan digunakan pada waktu kompilasi memeriksa kode Anda.Ketika Anda ingin menggunakannya:
1- Antarmuka Anda tidak boleh memiliki lebih dari satu metode abstrak, jika tidak, kesalahan kompilasi akan diberikan.
1- Antarmuka Anda Harus murni, yang berarti antarmuka fungsional dimaksudkan untuk diimplementasikan oleh kelas stateless, contoh
Comparator
antarmuka murni adalah karena itu tidak tergantung pada negara pelaksana, dalam hal ini Tidak ada kesalahan kompilasi yang akan diberikan, tetapi dalam banyak kasus Anda tidak akan dapat menggunakan lambda dengan antarmuka semacam iniThe
java.util.function
paket berisi berbagai antarmuka fungsional tujuan umum sepertiPredicate
,Consumer
,Function
, danSupplier
.Perlu diketahui juga bahwa Anda dapat menggunakan lambdas tanpa anotasi ini.
sumber
Selain jawaban lain, saya pikir alasan utama untuk "mengapa menggunakan Antarmuka Fungsional selain langsung dengan ekspresi lambda" dapat dikaitkan dengan sifat bahasa Jawa yang Berorientasi Objek.
Atribut utama ekspresi Lambda adalah: 1. Mereka dapat diedarkan sekitar 2. dan mereka dapat dieksekusi di masa depan dalam waktu tertentu (beberapa kali). Sekarang untuk mendukung fitur ini dalam bahasa, beberapa bahasa lain hanya berurusan dengan masalah ini.
Misalnya dalam Java Script, fungsi (fungsi Anonim, atau Fungsi literal) dapat dialamatkan sebagai objek. Jadi, Anda dapat membuatnya secara sederhana dan mereka juga dapat ditugaskan ke variabel dan sebagainya. Sebagai contoh:
atau melalui ES6, Anda dapat menggunakan fungsi panah.
Hingga kini, perancang bahasa Jawa belum menerima untuk menangani fitur yang disebutkan melalui cara ini (teknik pemrograman fungsional). Mereka percaya bahwa bahasa Jawa adalah Object Oriented dan oleh karena itu mereka harus menyelesaikan masalah ini melalui teknik Object Oriented. Mereka tidak ingin ketinggalan kesederhanaan dan konsistensi bahasa Jawa.
Oleh karena itu, mereka menggunakan antarmuka, seperti ketika objek antarmuka hanya dengan satu metode (maksud saya antarmuka fungsional) diperlukan, Anda dapat menggantinya dengan ekspresi lambda. Seperti:
sumber