J2ObjC mendukung penyematan Objective-C ke dalam metode native Java, sangat mirip dengan cara JSNI GWT mendukung penyematan JavaScript. Perbedaan utama antara penyematan J2ObjC dan GWT adalah J2ObjC menggunakan /*-[
dan ]-*/
untuk menandai kode Objective-C. Fasilitas ini disebut OCNI (Objective-C Native Interface), untuk membedakan diri dari JSNI GWT.
Berikut ini contoh dari java.lang.System
versi library emulasi JRE:
public static native long currentTimeMillis() /*-[
// Use NSDate
return (long long) ([[NSDate date] timeIntervalSince1970] * 1000);
]-*/;
J2ObjC menyalin komentar, tanpa pemisah, untuk membuat isi metode:
+ (long long int)currentTimeMillis {
// Use NSDate
return (long long) ([[NSDate date] timeIntervalSince1970] * 1000);
}
Impor Native
J2ObjC memindai kode Java yang diterjemahkan guna menambahkan perintah #import untuk dependensinya, serta mengimpor framework Foundation. Namun, semua impor yang hanya diperlukan oleh kode native perlu ditambahkan secara terpisah. Untuk menambahkan impor, tambahkan bagian OCNI di atas class pertama dalam file sumber Java dan tentukan impor di sana; misalnya:
package my.project;
/*-[
#import "java/lang/NullPointerException.h"
]-*/
public class Test {
native void test() /*-[
@throw [[JavaLangNullPointerException alloc] init];
]-*/;
}
Impor diperlukan dalam contoh di atas karena satu-satunya tempat jenis tersebut yang dirujuk adalah dalam kode native.
Pemblokiran Native
Dalam isi class, J2ObjC memindai blok OCNI. Blok ini ditambahkan tanpa dimodifikasi ke file terjemahan, di posisi yang sama relatif terhadap anggota class yang diterjemahkan. Berikut contohnya:
/*-[
static void log(NSString *msg) {
NSLog(@"%@", msg);
}
]-*/;
Fungsi C ini dapat dipanggil dari metode native apa pun yang dideklarasikan setelah blok OCNI ini.
Varian khusus dari blok OCNI ini menyisipkan kode dalam header yang dihasilkan,
bukan file .m: /*-HEADER[...]
Memanggil Metode Java dari Kode Native
public native void bar(JSNIExample x, String s) /*-[
// Call instance method instanceFoo() on this
[self instanceFooWithNSString:s];
// Call instance method instanceFoo() on x
[x instanceFooWithNSString:s];
// Call static method staticFoo()
JSNIExample_staticFooWithNSString_(s);
]-*/;
Mengakses kolom dari Kode Native
Untuk membaca kolom instance, gunakan myInstanceField_
atau
self->myInstanceField_
. Akhiran di akhir akan menghindari bentrok dengan metode yang memiliki nama yang sama.
Perhatikan bahwa kolom yang memiliki nama yang dicadangkan akan memiliki dua garis bawah. Misalnya, kolom bernama "id" legal di Java, tetapi tidak di Objective C. Saat diterjemahkan, kolom tersebut akan diberi nama "id__". Oleh karena itu, periksa file yang dibuat jika ada error compiler "no-such-field".
Untuk menulis ke kolom instance objek, gunakan JSNIExample_set_myInstanceField(string)
Membaca kolom statis: JSNIExample_get_myStaticField()
Tulis kolom statis: JSNIExample_set_myStaticField(value)
J2ObjC dan GWT
Pembatas yang berbeda dipilih sehingga pada rilis J2ObjC berikutnya, komentar GWT JSNI akan diabaikan (sebelumnya pemisah yang sama digunakan sebagai GWT). Ini berarti bahwa satu sumber Java dapat memiliki metode native yang memiliki implementasi Objective-C, GWT, dan Android (melalui JNI):
static native void log(String text) /*-{ // left-brace for JavaScript
console.log(text);
}-*/ /*-[ // left-bracket for Objective-C
NSLog(@"%@", text);
]-*/;
J2ObjC dan Android
Implementasi metode native Android dan J2ObjC "langsung berfungsi", karena metode native Android diimplementasikan dalam file JNI C atau C++ yang terpisah. Semua komentar OCNI di class Java akan dihapus saat dikompilasi oleh javac untuk Android atau platform Java lainnya.