כתיבת שיטות מותאמות

J2ObjC תומך בהטמעת Objective-C בשיטות מקוריות ב-Java, בדומה לאופן שבו JSNI של GWT תומך בהטמעת JavaScript. ההבדל העיקרי בין הטמעת J2ObjC לבין GWT הוא ש-J2ObjC משתמש ב-/*-[ וב-]-*/ כדי לקבוע את הקוד של Objective-C. המתקן הזה נקרא OCNI (Objective-C Native Interface), כך שהוא יכול לבדל את עצמו מ-JSNI של GWT.

הנה דוגמה מהגרסה של java.lang.System בספריית האמולציה של JRE:

  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 ביחס ליחסי התלות שלו, וגם כדי לייבא את ה-Basic framework. עם זאת, את כל הייבואים שנדרשים רק באמצעות קוד Native יש להוסיף בנפרד. כדי להוסיף פעולות ייבוא, מוסיפים קטע OCNI מעל המחלקה הראשונה בקובץ המקור של Java, ומציינים שם את תהליכי הייבוא. לדוגמה:

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

ניתן להפעיל את הפונקציה C הזאת מכל שיטה מקורית שהוצהרה אחרי חסימת ה-OCNI הזו.

וריאנט מיוחד של בלוק ה-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, אבל לא למטרה ג'. אחרי התרגום, השדה הזה ייקרא "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++. תגובות OCNI במחלקות Java יוסרו במהלך ההדרה על ידי javac ל-Android או לכל פלטפורמת Java אחרת.