Search code examples
javac++java-native-interface

Is there any method to test two jobject are from the same class?


For JNI, I have two jobject jobj1 and jobj2, how can I test that they are the instance of the same class?

I want to test whether two jobject jobj1 and jobj2 are the instance of the same class.

JNIEXPORT jboolean JNICALL TestTwoObjectEqual
    (JNIEnv *env, jclass jclazz, jobject jobj1, jobject jobj2);

I tried jclass cls_arraylist1 = env->GetObjectClass(jobj1); 
jclass cls_arraylist2 = env->GetObjectClass(jobj2); 

Then compare *cls_arraylist1 == *cls_arraylist2, but == is not defined.

How can I test whether jobj1 and jobj2 are the instance of the same class of JAVA.


Solution

  • bool testTwoObjectEqual(JNIEnv *env, jobject jobj1, jobject jobj2) {
        jclass cls1 = env->GetObjectClass(jobj1);
        jclass cls2 = env->GetObjectClass(jobj2);
        bool res = env->IsInstanceOf(jobj1, cls2) && env->IsInstanceOf(jobj2, cls1);
        env->FreeLocalRef(cls1);
        env->FreeLocalRef(cls2);
        return res;
    }
    

    You can easily make this test less strict if jobj2 may be derived from the class of jobj1. But maybe it's OK that both objects are derived from the same base class, e.g. from java.util.ArrayList — then you must supply this class to your test method.

    If you want to know that jobj1 and jobj2 are ArrayLists of the same type, you must inspect the elements of these lists, because the information about the generics is compile-time only:

    • check that jobj1 is instance of ArrayList
    • check that jobj2 is instance of ArrayList
    • get first non-null element of jobj1, jel1
    • get first non-null element of jobj2, jel2
    • check that class of jel1 is equal to class of jel2

    PS I don't really understand why you want to use a dedicated native method for this task; as other (deleted) answers propose, this is a one-liner in Java, and they are easier to understand and have no performance concerns. This function is only relevant as a building block of a bigger JNI library, therefore you need to free all local references before return.