Apakah mungkin untuk mengakses fungsi ekstensi dari kode Java?
Saya mendefinisikan fungsi ekstensi dalam file Kotlin.
package com.test.extensions
import com.test.model.MyModel
/**
*
*/
public fun MyModel.bar(): Int {
return this.name.length()
}
Di mana MyModel
kelas java (dihasilkan). Sekarang, saya ingin mengaksesnya dalam kode java normal saya:
MyModel model = new MyModel();
model.bar();
Namun, itu tidak berhasil. IDE tidak akan mengenali bar()
metode dan kompilasi gagal.
Apa yang berhasil digunakan dengan fungsi statis dari kotlin:
public fun bar(): Int {
return 2*2
}
dengan menggunakan import com.test.extensions.ExtensionsPackage
IDE saya sepertinya sudah terkonfigurasi dengan benar.
Saya mencari melalui seluruh file Java-interop dari dokumen kotlin dan juga banyak googled, tetapi saya tidak dapat menemukannya.
Apa yang saya lakukan salah? Apakah ini mungkin?
java
kotlin
extension-function
Lovis
sumber
sumber
import package com.test.extensions.MyModel
?com.test.extensions.ExtensionsPackage
Jawaban:
Semua fungsi Kotlin yang dideklarasikan dalam file akan dikompilasi secara default ke metode statis di kelas dalam paket yang sama dan dengan nama yang berasal dari file sumber Kotlin (huruf kapital pertama dan ekstensi ".kt" diganti dengan akhiran "Kt" ) . Metode yang dihasilkan untuk fungsi ekstensi akan memiliki parameter pertama tambahan dengan jenis penerima fungsi ekstensi.
Menerapkannya ke pertanyaan awal, kompiler Java akan melihat file sumber Kotlin dengan nama example.kt
seolah-olah kelas Java berikut dideklarasikan
Karena tidak ada yang terjadi dengan kelas yang diperluas dari sudut pandang Java, Anda tidak bisa hanya menggunakan sintaks dot untuk mengakses metode tersebut. Tetapi mereka masih bisa dipanggil sebagai metode statis Java normal:
Impor statis dapat digunakan untuk kelas ExampleKt:
sumber
bar(model, param1, param2);
Fungsi ekstensi tingkat atas Kotlin dikompilasi sebagai metode statis Java.
File Kotlin yang diberikan
Extensions.kt
dalam paketfoo.bar
berisi:Kode Java yang setara adalah:
Kecuali, jika ada,
Extensions.kt
mengandung garisDalam hal ini kelas statis Java akan dinamai
DemoUtils
Di Kotlin, metode ekstensi dapat dideklarasikan dengan cara lain. (Misalnya, sebagai fungsi anggota atau sebagai perpanjangan dari objek pendamping.)
sumber
Saya memiliki file Kotlin bernama NumberFormatting.kt yang memiliki fungsi sebagai berikut
Di java saya sederhana mengaksesnya melalui file NumberFormattingKt dengan cara berikut setelah impor diperlukan
import ....extensions.NumberFormattingKt;
sumber
Anda selalu dapat melihat kode Java aktual yang dihasilkan dari kode Kotlin Anda dengan membuka
Tools > Kotlin > Show Kotlin Bytecode
, lalu mengklikDecompile
. Ini dapat sangat membantu Anda. Dalam kasus Anda, kode Java akan terlihat seperti ini jika adaMyModelExtensions.kt
Anda dapat memperbaikinya dengan menggunakan
@JvmName
file yang berisibar
:dan itu akan menghasilkan kode ini:
Penggunaan
MyModels
sesuai dengan apa yang disarankan Java Efektif untuk kelas utilitas. Anda juga dapat mengubah nama metode Anda seperti ini:kemudian dari sisi Jawa akan terlihat idiomatis:
sumber
Anda perlu menduplikasi fungsi Anda di file kelas:
Buat file Kotlin, untuk ex Utils.kt
Masukkan kodenya
ATAU
Dalam penggunaan kotlin:
Di Jawa gunakan ini:
sumber
Ini bekerja untuk saya:
Kotlin
Kode Java
Proyek saya adalah proyek android lama yang dibuat dengan Java; sekarang saya membuat file kotlin pertama dan menambahkan String extensions fun String.isNotNullOrEmpty (): Boolean {...}
dan saya bisa menyebutnya dari file java menggunakan: StringUtilsKt.isNotNullOrEmpty (thestring).
Nama file kotlin saya adalah StringUtils
sumber
Jawaban lain di sini mencakup kasus memanggil fungsi ekstensi yang terletak di bagian atas file paket Kotlin.
Namun, kasus saya adalah bahwa saya perlu memanggil fungsi Extension yang terletak di dalam Kelas. Secara khusus, saya berurusan dengan sebuah Object.
Solusinya sangat sederhana .
Yang harus Anda lakukan adalah membubuhi keterangan fungsi ekstensi Anda sebagai
@JvmStatic
, dan voila! Kode Java Anda akan dapat mengaksesnya dan menggunakannya.sumber
Ketika Anda memperluas kelas seperti ini:
Ini akan dikompilasi untuk ini:
Ada lebih banyak contoh di sini .
sumber
Sejauh yang saya tahu ini tidak mungkin. Dari pembacaan saya tentang ekstensi dokumen, tampaknya itu
menciptakan metode baru dengan tanda tangan
Kemudian, Kotlin memetakan yang berfungsi untuk panggilan formulir
myModel.bar()
, di mana jikabar()
tidak ditemukan diMyModel
kelas itu mencari metode statis yang cocok dengan tanda tangan dan skema penamaan yang dihasilkannya. Perhatikan bahwa ini hanya asumsi dari pernyataan mereka tentang ekstensi yang diimpor secara statis dan tidak mengabaikan metode yang ditentukan. Saya belum mendapatkan sumber yang cukup jauh untuk mengetahui dengan pasti.Jadi, dengan asumsi di atas benar tidak ada cara untuk ekstensi Kotlin dipanggil dari kode java lama, karena kompiler hanya akan melihat metode yang tidak diketahui dipanggil pada objek dan kesalahan keluar.
sumber