Menulis Metode Native

J2ObjC mendukung penyematan Objective-C ke dalam metode native Java, JSNI GWT mendukung Penyematan JavaScript. Perbedaan utama antara embedding J2ObjC dan GWT adalah bahwa J2ObjC menggunakan /*-[ dan ]-*/ untuk menandai kode Objective-C. Fasilitas ini disebut OCNI (Objective-C) Native Interface), untuk membedakannya dari JSNI GWT.

Berikut adalah contoh dari versi java.lang.System library emulasi JRE:

  public static native long currentTimeMillis() /*-[
    // Use NSDate
    return (long long) ([[NSDate date] timeIntervalSince1970] * 1000);
  ]-*/;

J2ObjC menyalin komentar, dikurangi {i>delimiter<i}, 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 untuk menambahkan perintah #import untuk dependensinya, saat mengimpor framework Foundation. Namun, impor apa pun yang diperlukan hanya oleh kode native harus ditambahkan secara terpisah. Untuk menambahkan impor, tambahkan bagian OCNI di atas class pertama dalam file sumber Java dan menentukan 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 ini direferensikan adalah di kode native 3D.

Pemblokiran Native

Dalam isi class, J2ObjC memindai blok OCNI. Blok ini ditambahkan tanpa dimodifikasi ke yang diterjemahkan, di posisi yang sama relatif terhadap anggota kelas 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 di header yang dihasilkan dari 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 menghindari konflik dengan metode 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. Jika diterjemahkan, bidang tersebut akan diberi nama "id__". Oleh karena itu, periksa file yang dihasilkan jika tidak ada "no-such-field" error compiler.

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

{i>Delimiter<i} yang berbeda dipilih sehingga dalam rilis J2ObjC berikutnya, komentar GWT JSNI akan diabaikan (sebelumnya {i>delimiter<i} 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 J2ObjC dan Android "langsung berfungsi", karena metode native Android diimplementasikan dalam file JNI C atau C++ terpisah. Semua komentar OCNI di class Java akan dihapus jika dikompilasi oleh javac untuk Android atau platform Java lainnya.