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

相关文章

Go语言中make和new的区别及说明

《Go语言中make和new的区别及说明》:本文主要介绍Go语言中make和new的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1 概述2 new 函数2.1 功能2.2 语法2.3 初始化案例3 make 函数3.1 功能3.2 语法3.3 初始化

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

深度解析Spring Boot拦截器Interceptor与过滤器Filter的区别与实战指南

《深度解析SpringBoot拦截器Interceptor与过滤器Filter的区别与实战指南》本文深度解析SpringBoot中拦截器与过滤器的区别,涵盖执行顺序、依赖关系、异常处理等核心差异,并... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现

CSS中的Static、Relative、Absolute、Fixed、Sticky的应用与详细对比

《CSS中的Static、Relative、Absolute、Fixed、Sticky的应用与详细对比》CSS中的position属性用于控制元素的定位方式,不同的定位方式会影响元素在页面中的布... css 中的 position 属性用于控制元素的定位方式,不同的定位方式会影响元素在页面中的布局和层叠关

Before和BeforeClass的区别及说明

《Before和BeforeClass的区别及说明》:本文主要介绍Before和BeforeClass的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Before和BeforeClass的区别一个简单的例子当运行这个测试类时总结Before和Befor

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

Linux中的more 和 less区别对比分析

《Linux中的more和less区别对比分析》在Linux/Unix系统中,more和less都是用于分页查看文本文件的命令,但less是more的增强版,功能更强大,:本文主要介绍Linu... 目录1. 基础功能对比2. 常用操作对比less 的操作3. 实际使用示例4. 为什么推荐 less?5.

Java 关键字transient与注解@Transient的区别用途解析

《Java关键字transient与注解@Transient的区别用途解析》在Java中,transient是一个关键字,用于声明一个字段不会被序列化,这篇文章给大家介绍了Java关键字transi... 在Java中,transient 是一个关键字,用于声明一个字段不会被序列化。当一个对象被序列化时,被

解读@ConfigurationProperties和@value的区别

《解读@ConfigurationProperties和@value的区别》:本文主要介绍@ConfigurationProperties和@value的区别及说明,具有很好的参考价值,希望对大家... 目录1. 功能对比2. 使用场景对比@ConfigurationProperties@Value3. 核

Spring Boot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)

《SpringBoot拦截器Interceptor与过滤器Filter深度解析(区别、实现与实战指南)》:本文主要介绍SpringBoot拦截器Interceptor与过滤器Filter深度解析... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)深度解析:区别、实现与实