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

J2ObjC תומך בהטמעת Objective-C בשיטות נייטיב של Java, הדומה מאוד JSNI של GWT תומך הטמעת JavaScript. ההבדל העיקרי בין הטמעת J2ObjC לבין GWT הוא ש-J2ObjC משתמש /*-[ ו-]-*/ כדי להגדיר את קוד Objective-C. המתקן הזה נקרא OCNI (Objective-C) ממשק מקורי), כדי להבדיל את עצמו מ-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 שמתורגם כדי להוסיף הוראות #לייבא ליחסי התלות שלו. שמייבאים את מסגרת היסודות. עם זאת, כל ייבוא הדרוש רק לצורך שימוש בקוד נייטיב צריך הם נוספו בנפרד. כדי להוסיף ייבוא, צריך להוסיף קטע 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 מקוד 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);
]-*/;

גישה לשדות מקוד Native

כדי לקרוא שדה של מופע, משתמשים ב-myInstanceField_ או self->myInstanceField_. הסיומת בסוף מונעת התנגשות עם methods בעלי שם זהה.

חשוב לזכור שבשדות עם שמות שמורים יש שני קווים תחתונים. לדוגמה, שדה בשם "id" חוקית ב-Java, אבל לא באובייקט ג'. כשהתרגום מתבצע, שם השדה הזה יהיה "id__". לכן, יש לבדוק את הקבצים שנוצרו אין שדות כאלה בשגיאות מהדר (compiler) .

כדי לכתוב בשדה של מופע אובייקט, משתמשים ב-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 אחרת.