Previous | Next | Trail Map | Integrating Native Code and Java Programs | Java Native Interface Programming


Accessing Java Arrays

Similar to jstring, jarray represents references to Java arrays and cannot be directly accessed in C. Our second example, IntArray.java, contains a native method that totals up the contents of an integer array. You cannot implement the native method by directly addressing the array elements:
/* This program is illegal! */
JNIEXPORT jint JNICALL
Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)
{
  int i, sum = 0;
  for (i=0; i<10; i++)
    sum += arr[i];

Instead, the JNI provides functions that allow you to obtain pointers to elements of integer arrays. The correct way to implement the above function is shown in the native method IntArray.c .

Accessing Arrays of Primitive Elements

First, obtain the length of the array by calling the JNI function GetArrayLength. Note that, unlike C arrays, Java arrays carry length information.

JNIEXPORT jint JNICALL
Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr)
{
  int i, sum = 0;
  jsize len = (*env)->GetArrayLength(env, arr);

Next, obtain a pointer to the elements of the integer array. Our example uses GetIntArrayElements to obtain this pointer. You can use normal C operations on the resulting integer array.

  jint *body = (*env)->GetIntArrayElements(env, arr, 0);
  for (i=0; i<len; i++)
    sum += body[i];

While, in general, Java arrays may be moved by the garbage collector, the Virtual Machine guarantees that the result of GetIntArrayElements points to a nonmovable array of integers. The JNI will either "pin" down the array , or it will make a copy of the array into nonmovable memory. When the native code has finished using the array, it must call ReleaseIntArrayElements, as follows:

  (*env)->ReleaseIntArrayElements(env, arr, body, 0);
  return sum;
}
ReleaseIntArrayElements enables the JNI to copy back and free body if it is a copy of the original Java array, or "unpin" the Java array if it has been pinned in memory. Forgetting to call ReleaseIntArrayElements results in either pinning the array for an extended period of time, or not being able to reclaim the memory used to store the nonmovable copy of the array.

The JNI provides a set of functions to access arrays of every primitive type, including boolean, byte, char, short, int, long, float, and double:

Accessing a Small Number of Elements

Note that the Get<type>ArrayElements function might result in the entire array being copied. If you are only interested in a small number of elements in a (potentially) large array, you should instead use the Get/Set<type>ArrayRegion functions. These functions allow you to access, via copying, a small set of elements in an array.

Accessing Arrays of Objects

The JNI provides a separate set of function to access elements of object arrays. You can get and set individual object array elements. You cannot get all the object array elements at once.


Previous | Next | Trail Map | Integrating Native Code and Java Programs | Java Native Interface Programming