Scrittura di metodi nativi

J2ObjC supporta l'incorporamento di Objective-C nei metodi nativi Java, in modo molto simile a come JSNI di GWT supporta l'incorporamento di JavaScript. La differenza principale tra l'incorporamento di J2ObjC e quello di GWT è che J2ObjC utilizza /*-[ e ]-*/ per delineare il codice Objective-C. Questa struttura è denominata OCNI (Objective-C Native Interface), per distinguersi dalla libreria JSNI di GWT.

Ecco un esempio dalla versione di java.lang.System della libreria di emulazione JRE:

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

J2ObjC copia il commento, senza i delimitatori, per creare il corpo del metodo:

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

Importazioni native

J2ObjC esegue la scansione del codice Java da tradurre per aggiungere direttive #import per conoscere le sue dipendenze, oltre che per importare il framework di base. Tuttavia, tutte le importazioni necessarie solo per il codice nativo devono essere aggiunte separatamente. Per aggiungere importazioni, aggiungi una sezione OCNI sopra la prima classe nel file di origine Java e specifica le importazioni lì, ad esempio:

  package my.project;

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

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

L'importazione è necessaria nell'esempio precedente perché l'unica posizione a cui viene fatto riferimento a questo tipo è il codice nativo.

Blocchi nativi

All'interno di un corpo di classe, J2ObjC cerca i blocchi OCNI. Questi blocchi vengono aggiunti al file tradotto senza modifiche, nella stessa posizione rispetto ai membri della classe tradotti. Esempio:

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

Questa funzione C può essere richiamata da qualsiasi metodo nativo dichiarato dopo questo blocco OCNI.

Una variante speciale di questo blocco OCNI inserisce il codice nell'intestazione generata invece del file .m: /*-HEADER[...]

Richiamo di metodi Java da codice nativo

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

Accesso ai campi da Native Code

Per leggere un campo istanza, utilizza myInstanceField_ o self->myInstanceField_. Il suffisso finale evita conflitti con metodi che hanno lo stesso nome.

Tieni presente che i campi che hanno nomi riservati avranno due trattini bassi. Ad esempio, un campo denominato "id" è legale in Java, ma non nell'Obiettivo C. Una volta tradotto, il campo sarà denominato "id__". Controlla quindi nei file generati se sono presenti errori del compilatore "no-such-field".

Per scrivere in un campo di istanza di oggetto, utilizza JSNIExample_set_myInstanceField(string)

Leggi un campo statico: JSNIExample_get_myStaticField()

Scrivi un campo statico: JSNIExample_set_myStaticField(value)

J2ObjC e GWT

Sono stati scelti diversi delimitatori in modo che nella prossima release di J2ObjC, i commenti GWT JSNI verranno ignorati (in precedenza erano utilizzati gli stessi delimitatori di GWT). Ciò significa che una singola origine Java può avere metodi nativi con implementazioni Objective-C, GWT e Android (tramite JNI):

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

J2ObjC e Android

Le implementazioni dei metodi nativi di J2ObjC e Android "funzionano" perché i metodi nativi Android vengono implementati in un file JNI C o C++ separato. Tutti i commenti OCNI nelle classi Java vengono rimossi se compilati da Javac per Android o da qualsiasi altra piattaforma Java.