Search code examples
carraysjava-native-interface

JNI : create an jobjectArray without knowing the size in advance


I would like to return an array of strings from C to Java using JNI. I saw that I could use NewObjectArray() this way:

JNIEXPORT jobjectArray JNICALL Java_Array_initStringArray(JNIEnv *env, jclass cls, jint size)
{
 jclass stringCls = (*env)->FindClass(env, "Ljava/lang/String;");
 if (stringCls == NULL) return NULL;

 jstringArray result = (*env)->NewObjectArray(env, size, StringCls, NULL);
 if (result == NULL) return NULL; 
 ...
}

But here, I don't know the int size parameter: I don't know the number of strings I'll use to populate my array. So is there a way to create an jobjectArray without knowing in advance the size of the array?

Something like creating an empty array and then adding jobject one by one to that array?


EDIT : solution using an ArrayList as Edwin suggested

jclass arrayClass = (*jenv)->FindClass(jenv, "java/util/ArrayList");
  if (arrayClass == NULL)   return NULL;

jmethodID mid_init =  (*jenv)->GetMethodID(jenv, arrayClass, "<init>", "()V");
  if (mid_init == NULL) return NULL;

jobject objArr = (*jenv)->NewObject(jenv, arrayClass, mid_init));
  if (objArr == NULL) return NULL;

mid_add = (*jenv)->GetMethodID(jenv, arrayClass, "add", "(Ljava/lang/Object;)Z");
  if (mid_add == NULL) return NULL;

Then in a loop I create an jobject obj for each new object I need to add to the arrayList:

jboolean jbool = (*jenv)->CallBooleanMethod(jenv, objArr, mid_add, obj);
  if (jbool == NULL) return NULL;

Solution

  • If you want to have the backing store (the array) grow as you add to it, use a java.util.ArrayList. It might mean a few more JNI calls (to set up the object), but in your case it sounds like it's worth the effort.