編寫原生方法

J2ObjC 支援將 Objective-C 嵌入 Java 原生方法,類似於 GWT 的 JSNI 支援 JavaScript 嵌入的方式。J2ObjC 嵌入與 GWT 的主要差異在於 J2ObjC 使用 /*-[]-*/ 來描述 Objective-C 程式碼。這個設施稱為 OCNI (Objective-C 原生介面),以便與 GWT 的 JSNI 區別。

以下是 JRE 模擬程式庫版本的 java.lang.System 範例:

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

J2ObjC 複製註解 (減去分隔符號) 來建立方法主體:

  + (long long int)currentTimeMillis {
    // Use NSDate
    return (long long) ([[NSDate date] timeIntervalSince1970] * 1000);
  }

原生匯入

J2ObjC 會掃描要翻譯的 Java 程式碼,為其依附元件新增 #import 指令,以及匯入基礎架構。但是,只有原生程式碼需要的匯入作業必須分開新增。如要新增匯入作業,請在 Java 來源檔案的第一個類別上方新增 OCNI 區段,並在其中指定匯入作業,例如:

  package my.project;

  /*-[
  #import "java/lang/NullPointerException.h"
  ]-*/

  public class Test {
    native void test() /*-[
      @throw [[JavaLangNullPointerException alloc] init];
    ]-*/;
  }

在上述範例中,匯入作業是必要步驟,因為原生程式碼中唯一參照該類型的位置。

原生區塊

在類別主體中,J2ObjC 會掃描 OCNI 區塊。這些區塊會未經修改,新增至翻譯檔案,位置會與翻譯後的類別成員位於相同位置。範例如下:

  /*-[
    static void log(NSString *msg) {
      NSLog(@"%@", msg);
    }
  ]-*/;

您可透過在此 OCNI 區塊之後宣告的任何原生方法叫用這個 C 函式。

這個 OCNI 區塊的特殊變化版本會在產生的標頭中插入程式碼,而不是 .m 檔案:/*-HEADER[...]

從原生程式碼叫用 Java 方法

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);
]-*/;

從原生程式碼存取欄位

如要讀取執行個體欄位,請使用 myInstanceField_self->myInstanceField_。結尾的後置字串可避免與方法同名的方法發生衝突。

請注意,採用保留名稱的欄位會有兩個底線。舉例來說,名為「id」的欄位在 Java 中是合法的,但在 Goal C 中則不合法。翻譯後,該欄位的名稱將會是「id__」。因此,如果出現「no-such-field」編譯器錯誤,請檢查產生的檔案。

如要寫入物件例項欄位,請使用 JSNIExample_set_myInstanceField(string)

讀取靜態欄位:JSNIExample_get_myStaticField()

編寫靜態欄位:JSNIExample_set_myStaticField(value)

J2ObjC 和 GWT

選擇不同分隔符號,因此在下一個 J2ObjC 版本中,系統會忽略 GWT JSNI 註解 (先前使用的分隔符號與 GWT 相同)。這表示單一 Java 原始碼可擁有包含 Objective-C、GWT 和 Android (透過 JNI) 實作的原生方法:

  static native void log(String text) /*-{ // left-brace for JavaScript
    console.log(text);
  }-*/ /*-[                                // left-bracket for Objective-C
     NSLog(@"%@", text);
  ]-*/;

J2ObjC 和 Android

J2ObjC 和 Android 原生方法的實作「運作正常」,因為 Android 原生方法會在單獨的 JNI C 或 C++ 檔案中實作。Java 類別中的所有 OCNI 註解都會在針對 Android 或任何其他 Java 平台的 javac 編譯時移除。