Java Native Interface
このことはJava配列についても同様である。例えばjintArrayはJavaのint[]型への間接参照であり、C/C++のポインタ型int*とは無関係である。
配列の全ての要素の合計を得る例を用いて以下に示す。
JavaのnullはC/C++のNULLポインタにマッピングされる。
String型インスタンスやClass型インスタンスなどのJavaオブジェクト参照をObject型変数に代入可能であるように、jstringやjclassなどの「JNIオブジェクト参照」もまたjobject型変数に代入可能である。
なお、Javaの文字型および文字列型の内部表現はUTF-16であり、jstringに対してGetStringChars()関数を使用することで、UTF-16形式の文字列バッファへのポインタjchar*を得ることができる(ただしゼロ終端ではなく、文字列の長さは別途GetStringLength()関数で取得する)。バッファへのポインタが不要になった場合はReleaseStringChars()関数で解放する必要がある。また、NewString()関数を用いることで、UTF-16バッファからjstringを生成することができる。jcharはUTF-16を表現できるデータ型であることが保証されるため、C++11で追加されたchar16_tなど、UTF-16用データ型との相互変換が可能である。
特に断りがない限り、JNIのAPI関数が返却するJNIオブジェクト参照は、Javaオブジェクトへの「ローカル参照」を表すポインタである。これはJavaの参照型ローカル変数に相当する。ローカル参照はスタックフレームの制御フローがJava側に返る際に自動的に削除され、Javaオブジェクトはガベージコレクションの管理対象となるが、DeleteLocalRef()関数を使って手動で削除することもできる。
JNIオブジェクト参照を長期間保持する場合は、「グローバル参照」を使わなければならない。
具体的には、C/C++側の静的変数(グローバル変数)などのヒープ領域にjobjectを格納する場合や、スレッド間でjobjectを共有する場合に、ローカル参照ではなくグローバル参照を用いる。NewGlobalRef()関数を呼び出すことで、ローカル参照からグローバル参照を生成することができる。
Javaのスレッドから呼ばれたC関数内でローカル参照を作成した場合、スタックフレームの制御フローがJava側に戻った時点でローカル参照は自動解放される。