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

posted @ 2025-08-15 19:00  tomato-haha  阅读(9)  评论(0)    收藏  举报