前面写了c++中调用Java中的属性和一般方法,这一篇记一下CallNonvitual<TYPE>Method方法的用法,调用Java父类里的相同方法。
在Java中如果有一个子类继承了父类的方法,如有个Father类和Child类,如果在java中如下输入:
Father p = new Child();
p.function();
其中function在两个类里都有,则用的是Child类里面的方法。用C++调用java的这个方法时,就可以用父类中的这个方法。
像我们在Java工程中建立两个类,一个Father类和一个Child类,当然是继承关系:
Father类:
public class Father {
public void function(){
System.out.println("Father:function");
}
}
Child类:
public class Child extends Father {
@Override
public void function() {
// TODO Auto-generated method stub
System.out.println("Child:function");
}
}
好了之后,在主类中写一个:
public Father p = new Child();
接下来就在C++中用本地方法来获得p这个对象,然后再调用p里面的function方法,看看调用的是哪一个类的方法:
JNIEXPORT void JNICALL Java_com_wang_TestNative_sayHello
(JNIEnv *env, jobject obj){
jclass class_TestNative = env->GetObjectClass(obj);
jfieldID id_p = env->GetFieldID(class_TestNative,"p","Lcom/wang/Father;");
jobject p = env->GetObjectField(obj,id_p);
jclass class_Father = env->FindClass("com/wang/Father");
jmethodID id_function = env->GetMethodID(class_Father,"function","()V");
env->CallVoidMethod(p,id_function);
}
首先还是获取调用sayHello方法的类,然后获得类里面的p属性,其属性是Father类型的,然后因为要用function方法,又因为p是Father类型的声明,所以要在C++中获取
Father类,用FindClass获取,因为Father类的完整包名是com.wang.Father,所以参数为“com/wang/Fahter”。。。
然后获得Father类中的function方法ID,用CallVoidMethod就可以调用function方法了,参数是p和它的方法ID。
而后编译,再在eclipse下运行,就会发现结果,输出的是:
Child:function
输出了子类的方法!
原因就在于在java中p“new”的是一个Child对象,上面的c++代码就相当于在java中实现p.function();尽管是父类声明,但实例化为Child。
接下来我们改一下C++中的代码:
最后一句改为:
//env->CallVoidMethod(p,id_function);
env->CallNonvirtualVoidMethod(p,class_Father,id_function);
用上CallNonvirtualVoidMethod方法,把Father的jclass参数传进去,再编译输出,就会发现输出的结果是:
Father:function
于是我们就用上了父类中的方法。。。。