The Java TM Tutorial

| Start of Tutorial > Start of Trail > Start of Lesson | Search

Trail: Java Native Interface
Lesson: Interacting with Java from the Native Side

## JNI Programming in C++

> The JNI provides a slightly cleaner interface for C++ programmers. The `jni.h` file contains a set of inline C++ functions. This allows the native method programmer to simply write:

> >     jclass cls = env->FindClass("java/lang/String");

> instead of:

> >     jclass cls = (*env)->FindClass(env, "java/lang/String");

> The extra level of indirection on `env` and the `env` argument to `FindClass` is hidden from the programmer. The C++ compiler simply expands out the C++ member function calls to their C counterparts; therefore, the resulting code is exactly the same.

> The `jni.h` file also defines a set of dummy C++ classes to enforce the subtyping relationships among different variations of `jobject` types:

> >     class _jobject {};
> >     class _jclass : public _jobject {};
> >     class _jthrowable : public _jobject {};
> >     class _jstring : public _jobject {};
> >     ... /* more on jarray */

> >     typedef _jobject *jobject;
> >     typedef _jclass *jclass;
> >     typedef _jthrowable *jthrowable;
> >     typedef _jstring *jstring;
> >     ... /* more on jarray */

> The C++ compiler is therefore better able than the C compiler to detect when incorrect types are passed to methods. For example, it is incorrect to pass a `jobject` to `GetMethodID` because `GetMethodID` expects a `jclass`. You can see this by examining the `GetMethodID` signature:

> >     jmethodID GetMethodID(jclass clazz, const char *name, const char *sig);

> The C compiler treats `jclass` as the same as `jobject` because it makes this determination using the following `typedef` statement:

> >     typedef jobject jclass;

> Therefore a C compiler is not able to detect that you have mistakenly passed the method a `jobject` instead of `jclass`.

> The added type safety in C++ comes with a small inconvenience. Recall from Accessing Java Arrays that in C you can fetch a Java string from an array of strings and directly assign the result to a `jstring`, as follows:

> >     jstring jstr = (*env)->GetObjectArrayElement(env, arr, i);

> In C++, however, you need to insert an explicit conversion of the Java string to `jstring`:

> >     jstring jstr = (jstring)env->GetObjectArrayElement(arr, i);

> You must make this explicit conversion because `jstring` is a subtype of `jobject`, which is the return type of `GetObjectArrayElement`.

| Start of Tutorial > Start of Trail > Start of Lesson | Search