native和static native区别

2024-09-09 09:32
文章标签 区别 static native

本文主要是介绍native和static native区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文基于Hello JNI 
如有疑惑,请看之前几篇文章。

native 与 static native

java中

    public native String helloJni();public native static String helloJniStatic();
  • 1
  • 2
  • 1
  • 2

JNI中

JNIEXPORT jstring JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_helloJni(JNIEnv *, jobject);JNIEXPORT jstring JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_helloJniStatic(JNIEnv *, jclass);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

区别在于第二个参数是jobject还是jclass,和Java中static方法属于类而不属于对象一样,static 的native方法属于类,所以第二个参数是jclass而不是jobject。

jobject获取jclass

jclass cls = env->GetObjectClass(jobj);
  • 1
  • 1

注意:这里获取到的cls是已有对象的cls。

jclass获取jobject

jmethodID cid = env->GetMethodID(cls, "<init>", "()V");
jobject  jobj = env->NewObject(cls, cid);
  • 1
  • 2
  • 1
  • 2

注意:这里获取到的jobj已经是一个新的对象。

下面看一组对比Demo

通过jobject获取jclass,并修改对象中的age字段

JNIEXPORT jstring JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_helloJni(JNIEnv *env, jobject jobj){jclass cls = env->GetObjectClass(jobj);//2.获取age的jfieldID 注意用GetStaticFieldID方法jfieldID jfid = env->GetStaticFieldID(cls, "age", "I");//3.通过jfid获取age的属性值,注意用GetStaticIntFieldjint jage = env->GetStaticIntField(cls, jfid);jage += 10;//4.修改age的属性值,注意用GetStaticIntFieldenv->SetStaticIntField(cls,jfid, jage);return env->NewStringUTF("hello jni");}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

通过jclass获取jobject,然后修改courses数组中第一个元素的值

JNIEXPORT void jclsToJobj(JNIEnv *env, jclass cls) {jmethodID cid = env->GetMethodID(cls, "<init>", "()V");jobject  jobj = env->NewObject(cls, cid);jfieldID fid = env->GetFieldID(cls, "courses", "[Ljava/lang/String;");jobjectArray jarray = (jobjectArray) env->GetObjectField(jobj, fid);env->SetObjectArrayElement(jarray, 0, env->NewStringUTF("美术"));
}jstring JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_helloJniStatic(JNIEnv *env, jclass cls){//jclass 转换成 jobjectjclsToJobj(env, cls);//2.获取age的jfieldID 注意用GetStaticFieldID方法jfieldID jfid = env->GetStaticFieldID(cls, "age", "I");//3.通过jfid获取age的属性值,注意用GetStaticIntFieldjint jage = env->GetStaticIntField(cls, jfid);jage += 10;//4.修改age的属性值,注意用GetStaticIntFieldenv->SetStaticIntField(cls,jfid, jage);return env->NewStringUTF("hello jni static");
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

MainActivity.java中运行两个方法

        JniDemo jd = new JniDemo();Log.i(TAG, "age修改前: " + jd.age);Log.i(TAG, "helloJni->" + jd.helloJni());Log.i(TAG, "age修改后: " + jd.age);Log.i(TAG, "------------------------------------------");Log.i(TAG, "age修改前: " + jd.age);Log.i(TAG, "courses修改前: " + jd.courses[0]);JniDemo.helloJniStatic();Log.i(TAG, "age修改后: " + jd.age);Log.i(TAG, "courses修改后: " + jd.courses[0]);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

输出结果:

09-26 16:29:27.634 3969-3969/? I/MainActivity-: age修改前: 10
09-26 16:29:27.634 3969-3969/? I/MainActivity-: helloJni->hello jni
09-26 16:29:27.634 3969-3969/? I/MainActivity-: age修改后: 20
09-26 16:29:27.634 3969-3969/? I/MainActivity-: ------------------------------------------
09-26 16:29:27.634 3969-3969/? I/MainActivity-: age修改前: 20
09-26 16:29:27.634 3969-3969/? I/MainActivity-: courses修改前: 语文
09-26 16:29:27.634 3969-3969/? I/MainActivity-: age修改后: 30
09-26 16:29:27.634 3969-3969/? I/MainActivity-: courses修改后: 语文
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

可见通过jclass获取的jobject是一个新的对象,并不会改变已有对象的值。

这篇关于native和static native区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1150777

相关文章

GORM中Model和Table的区别及使用

《GORM中Model和Table的区别及使用》Model和Table是两种与数据库表交互的核心方法,但它们的用途和行为存在著差异,本文主要介绍了GORM中Model和Table的区别及使用,具有一... 目录1. Model 的作用与特点1.1 核心用途1.2 行为特点1.3 示例China编程代码2. Tab

Nginx指令add_header和proxy_set_header的区别及说明

《Nginx指令add_header和proxy_set_header的区别及说明》:本文主要介绍Nginx指令add_header和proxy_set_header的区别及说明,具有很好的参考价... 目录Nginx指令add_header和proxy_set_header区别如何理解反向代理?proxy

Java中&和&&以及|和||的区别、应用场景和代码示例

《Java中&和&&以及|和||的区别、应用场景和代码示例》:本文主要介绍Java中的逻辑运算符&、&&、|和||的区别,包括它们在布尔和整数类型上的应用,文中通过代码介绍的非常详细,需要的朋友可... 目录前言1. & 和 &&代码示例2. | 和 ||代码示例3. 为什么要使用 & 和 | 而不是总是使

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

Spring中@RestController和@Controller的使用及区别

《Spring中@RestController和@Controller的使用及区别》:本文主要介绍Spring中@RestController和@Controller的使用及区别,具有很好的参考价... 目录Spring中@RestController和@Controller使用及区别1. 基本定义2. 使

Qt 中 isHidden 和 isVisible 的区别与使用小结

《Qt中isHidden和isVisible的区别与使用小结》Qt中的isHidden()和isVisible()方法都用于查询组件显示或隐藏状态,然而,它们有很大的区别,了解它们对于正确操... 目录1. 基础概念2. 区别清见3. 实际案例4. 注意事项5. 总结1. 基础概念Qt 中的 isHidd

Spring、Spring Boot、Spring Cloud 的区别与联系分析

《Spring、SpringBoot、SpringCloud的区别与联系分析》Spring、SpringBoot和SpringCloud是Java开发中常用的框架,分别针对企业级应用开发、快速开... 目录1. Spring 框架2. Spring Boot3. Spring Cloud总结1. Sprin

Java中的runnable 和 callable 区别解析

《Java中的runnable和callable区别解析》Runnable接口用于定义不需要返回结果的任务,而Callable接口可以返回结果并抛出异常,通常与Future结合使用,Runnab... 目录1. Runnable接口1.1 Runnable的定义1.2 Runnable的特点1.3 使用Ru

Java中Runnable和Callable的区别和联系及使用场景

《Java中Runnable和Callable的区别和联系及使用场景》Java多线程有两个重要的接口,Runnable和Callable,分别提供一个run方法和call方法,二者是有较大差异的,本文... 目录一、Runnable使用场景二、Callable的使用场景三、关于Future和FutureTa

Java逻辑运算符之&&、|| 与&、 |的区别及应用

《Java逻辑运算符之&&、||与&、|的区别及应用》:本文主要介绍Java逻辑运算符之&&、||与&、|的区别及应用的相关资料,分别是&&、||与&、|,并探讨了它们在不同应用场景中... 目录前言一、基本概念与运算符介绍二、短路与与非短路与:&& 与 & 的区别1. &&:短路与(AND)2. &:非短