JNI 普通方法和静态方法本地的实现
一、JNI 中普通方法和静态方法的本地实现有什么区别?
1、JNI 定义native普通方法和静态方法
1 public class MyJniClass { 2 // native 普通方法 3 public native void NormalNativeMethod(); 4 5 // native 静态方法 6 public static native void StaticNativeMethod(); 7 8 static { 9 // 加载C++库 10 System.loadLibrary("myJni"); 11 } 12 }
2、JNI native C++本地实现代码
1 #include <jni.h> 2 3 JNIEXPORT void JNICALL Java_com_example_MyJniClass_NormalNativeMethod(JNIEnv* env, jobject obj) 4 { 5 // 在这里编写普通native方法的代码 6 } 7 8 JNIEXPORT void JNICALL Java_com_example_MyJniClass_StaticNativeMethod(JNIEnv* env, jclass clazz) 9 { 10 // 在这里编写静态native方法的代码 11 }
最大的区别就是本地实现第二个传入参数不同,jobject(类的对象)和 jclass(类)。
所以native普通方法、native静态方法,和Java的普通方法、静态方法是一样的,静态方法需要类就可以调用,普通方法需要类的对象才可以调用。
非要说的完整些,就把Java那套搬过去就行:
1、调用方式不同: 普通方法通过对象实例调用,而静态方法通过类名直接调用。 2、内存分配不同: 普通方法在每个对象实例中都有一份独立的内存空间, 而静态方法在类加载时就已经分配了内存空间,所有对象共享该方法。 3、访问权限不同: 普通方法可以访问类的所有成员(包括静态成员和非静态成员),而静态方法只能访问类的静态成员。 4、静态方法不能访问非静态成员: 由于静态方法在对象创建之前就已经存在,所以无法访问需要通过对象实例才能访问的非静态成员。 5、静态方法可以直接调用: 由于静态方法不依赖于对象实例,所以可以在没有创建对象的情况下直接调用。 6、静态方法不能被重写: 由于静态方法是通过类名直接调用的,所以无法被子类重写。
二、C++调用Java普通方法与静态方法的区别
1、Java 定义普通方法和静态方法
1 public class MyJniClass { 2 // 普通方法 3 public void NormalMethod() { 4 System.out.println("这是一个普通方法"); 5 } 6 7 // 静态方法 8 public static void StaticMethod() { 9 System.out.println("这是一个静态方法"); 10 } 11 }
2、JNI native C++本地实现代码
1 #include <jni.h> 2 3 JNIEXPORT void JNICALL Java_com_example_MyJniClass_NormalNativeMethod(JNIEnv* env, jobject obj) 4 { 5 // 获取MyJNIClass类 6 jclass clazz = env->FindClass("com/example/MyJniClass"); 7 8 // 获取普通方法的ID 9 jmethodID methodId = env->GetMethodID(clazz, "NormalMethod", "()V"); 10 11 // 创建MyJniClass对象 12 jobject jniObj = env->AllocObject(clazz); 13 14 // 调用普通方法 15 env->CallVoidMethod(jniObj, methodId); 16 } 17 18 JNIEXPORT void JNICALL Java_com_example_MyJniClass_StaticNativeMethod(JNIEnv* env, jobject obj) 19 { 20 // 获取MyJNIClass类 21 jclass clazz = env->FindClass("com/example/MyJniClass"); 22 23 // 获取静态方法的ID 24 jmethodID methodId = env->GetStaticMethodID(clazz, "StaticMethod", "()V"); 25 26 // 调用静态方法 27 env->CallStaticVoidMethod(clazz, methodId); 28 }
具体区别:
1、获取方法签名Id的api函数不同 GetMethodID 是获取普通方法签名Id的方法;GetStaticMethodID 是获取静态方法签名Id的方法; 2、需要的调用对象不同 静态方法使用类就可以调用,普通方法还要获取到类的对象; 3、反射执行调用普通方法和静态方法的api函数不同 CallVoidMethod 是普通方法执行的api函数,CallStaticVoidMethod 是静态方法执行的api函数; 这里只是一个举例,如果不是void的方法,那么api函数是不同的,比如调用一个返回Int的方法,反射调用的api函数就是 CallIntMethod,其他的方法以此类推。
参考自:
https://blog.csdn.net/qq_45649553/article/details/141328013
https://www.jianshu.com/p/0098a8002a9f

浙公网安备 33010602011771号