AndroidStudio下JNI开发(easy+1.0)之Java对象的传递与修改

概述

本文主要Java与C++之间的对象传递与取值。包括传递Java对象、返回Java对象、修改Java对象、以及性能对比。

通过JNIEnv完成数据转换

Java对象是存在于JVM虚拟机中的,而C++是脱离JVM而运行的,如果在C++中访问和使用Java中的对象,必然会使用JNIEnv这个桥梁。其实通过下面的代码很容易看出,这种访问方式和Java中的反射十分雷同。

这里定义一个简单Java对象用于下文测试:

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">package</span> com.example.wastrel.hellojni;
<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
 * Created by wastrel on 2016/8/24.
 */</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Bean</span> {</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> String msg;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> what;

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">Bean</span>(String msg,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> what)
    {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.msg=msg;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.what=what;
    }


    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> String <span class="hljs-title" style="box-sizing: border-box;">getMsg</span>() {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> msg;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setMsg</span>(String msg) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.msg = msg;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">getWhat</span>() {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> what;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setWhat</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> what) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.what = what;
    }

    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> String <span class="hljs-title" style="box-sizing: border-box;">toString</span>() {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Msg:"</span>+msg+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">";What:"</span>+what;
    }
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li></ul>

从C++中创建一个Java对象并返回

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Java中的native方法声明</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">native</span> Bean <span class="hljs-title" style="box-sizing: border-box;">newBean</span>(String msg,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> what);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
<code class="language-C++ hljs scala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//C++中的方法实现</span>
JNIEXPORT j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">JNICALL</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Java_com_example_wastrel_hellojni_HelloJNI_newBean</span></span>
        (JNIEnv *env, j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">obj</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">jstring</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">msg</span>,<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">jint</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">what</span>){</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//先找到class</span>
    j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">bean_clz</span>=<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">env</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">FindClass</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com/example/wastrel/hellojni/Bean"</span>)</span>;</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//在实际应用中应该确保你的class、method、field存在。减少此类判断。</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(bean_clz==NULL)
    {
        LOGE(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"can't find class"</span>);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> NULL;
    }
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//获取构造函数。构造函数的返回值是void,因此这里方法签名最后为V</span>
    jmethodID bean_init=env->GetMethodID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<init>"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"(Ljava/lang/String;I)V"</span>);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(bean_init==NULL)
    {
        LOGE(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"can't find init function"</span>);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> NULL;
    }
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//然后调用构造函数获得bean</span>
    j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">bean</span>=<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">env</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">NewObject</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(bean_clz,bean_init,msg,what)</span>;</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> bean;
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul>

注:如果提示找不到NULL 请include<stddef.h>

C++中解析Java对象

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//java方法Native声明</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">native</span> String <span class="hljs-title" style="box-sizing: border-box;">getString</span>(Bean bean);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
<code class="language-c++ hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//C++中的方法实现</span>
JNIEXPORT jstring JNICALL Java_com_example_wastrel_hellojni_HelloJNI_getString
        (JNIEnv <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*env</span>, jobject obj,jobject bean){
    jclass bean_clz=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->FindClass(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com/example/wastrel/hellojni/Bean"</span>);

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这部分是通过get函数去获取对应的值 </span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//    jmethodID bean_getmsg=env->GetMethodID(bean_clz,"getMsg","()Ljava/lang/String;");</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//    jmethodID bean_getwhat=env->GetMethodID(bean_clz,"getWhat","()I");</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//    jstring jmsg=(jstring)env->CallObjectMethod(bean,bean_getmsg);</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//    jint what=env->CallIntMethod(bean,bean_getwhat);</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//这部分是通过类的成员变量直接取获取值,你可能注意到在Java中定义的变量都是private修饰的,但在反射的调用下是毫无作用的。</span>
    jfieldID bean_fmsg=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->GetFieldID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msg"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Ljava/lang/String;"</span>);
    jfieldID bean_fwhat=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->GetFieldID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"what"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"I"</span>);
    jstring jmsg=(jstring)<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->GetObjectField(bean,bean_fmsg);
    jint  what=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->GetIntField(bean,bean_fwhat);

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//将拿到的值拼装一个String返回回去</span>
    const char * msg=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->GetStringUTFChars(jmsg,NULL);
    char <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*str</span>=new char[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1024</span>];
    sprintf(str,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Msg:%s;What:%d(From C++)"</span>,msg,what);
    jstring rs=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->NewStringUTF(str);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">delete</span>  []str;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->ReleaseStringUTFChars(jmsg,msg);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> rs;
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li></ul>

注:sprintf函数包含在stdio.h头文件中

C++中修改Java对象属性值

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//java方法Native声明</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">native</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">ModifyBean</span>(Bean bean);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//C++实现</span>
JNIEXPORT <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">void</span> JNICALL Java_com_example_wastrel_hellojni_HelloJNI_ModifyBean
        (JNIEnv <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>env, jobject obj,jobject bean){
    jclass bean_clz<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>FindClass(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com/example/wastrel/hellojni/Bean"</span>);
    jfieldID bean_fmsg<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>GetFieldID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msg"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Ljava/lang/String;"</span>);
    jfieldID bean_fwhat<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>GetFieldID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"what"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"I"</span>);
    jstring msg<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>NewStringUTF(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Modify in C++"</span>);
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//重新设置属性</span>
    env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>SetObjectField(bean,bean_fmsg,msg);
    env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>SetIntField(bean,bean_fwhat,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

结果图

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//java中调用代码</span>
        HelloJNI helloJNI=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> HelloJNI();
        Bean bean=helloJNI.newBean(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"This is from C++ bean"</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>);
        tv.setText(bean.toString());
        bean=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Bean(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"This is from Java bean"</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">15</span>);
        tv.append(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\n"</span>+helloJNI.getString(bean));
        helloJNI.ModifyBean(bean);
        tv.append(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\n"</span>+bean.toString());</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

这里写图片描述

Java中new Object和C++中new Object的性能对比

下面我们通过一个测试函数来比较通过两种方式的性能,这里可以毫无疑问的告诉你,Java一定比C++的快。那么这个对比的意义就在于,使用C++创建Java对象的时候会不会造成不可接受的卡顿。 
这里使用的测试机是华为Mate7,具体硬件配置可自行百度。 
测试函数如下:

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> Test(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> count)
    {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> startTime=System.currentTimeMillis();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;i<count;i++)
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Bean(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"123"</span>,i);
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> endTime=System.currentTimeMillis();
        Log.e(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Java"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Java new "</span>+count+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"s waste "</span>+(endTime-startTime)+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"ms"</span>);

        HelloJNI helloJNI=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> HelloJNI();
       startTime=System.currentTimeMillis();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;i<count;i++)
        {
            helloJNI.newBean(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"123"</span>,i);
        }
        endTime=System.currentTimeMillis();
        Log.e(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"C++"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"C++ new "</span>+count+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"s waste "</span>+(endTime-startTime)+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"ms"</span>);
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li></ul>

测试结果:

<code class="hljs http has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 5000s waste 3ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 5000s waste 38ms</span>

<span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 10000s waste 6ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 10000s waste 79ms</span>

<span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 50000s waste 56ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 50000s waste 338ms</span>

<span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 100000s waste 60ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 100000s waste 687ms</span></span></span></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

通过结果可以看出,通过C++来new对象比Java慢了足足10倍左右。但是从时间上来讲,如果只是在C++中new一个Java对象,几个微秒的时间差距完全是可以忽略不计的。

也许有人就会说,C++慢那么多是因为每次都在FindClass,GetMethodId,而在程序运行过程中这两个值是不会改变的。听起来确实有这样一个原因,下面我们将C++中的代码稍作修改缓存jclass和jmethodId。 
修改后的newBean函数:

<code class="language-C++ hljs scala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//用静态变量缓存</span>
static j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">bean_clz</span>=<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">NULL</span>;</span>
static jmethodID bean_init=NULL;
JNIEXPORT j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">JNICALL</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Java_com_example_wastrel_hellojni_HelloJNI_newBean</span></span>
        (JNIEnv *env, j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">obj</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">jstring</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">str</span>,<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">jint</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">what</span>){</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//先找到class</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(bean_clz==NULL)
    {
        j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span>  <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">_bean_clz</span>=<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">env</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">FindClass</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com/example/wastrel/hellojni/Bean"</span>)</span>;</span>
        bean_clz=(jclass)env->NewGlobalRef(_bean_clz);
    }
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//获取构造函数。构造函数的返回值是void,因此这里方法签名最后为V</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(bean_init==NULL)
    {
        bean_init=env->GetMethodID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<init>"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"(Ljava/lang/String;I)V"</span>);
    }
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//然后调用构造函数获得bean</span>
    j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">bean</span>=<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">env</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">NewObject</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(bean_clz,bean_init,str,what)</span>;</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> bean;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li></ul>

 你可能发现了缓存方法ID和缓存jclass似乎不一样。那是因为jclass其实是java.lang.Class对象,而方法ID是JNI中定义的一个结构体。如果这里不使用env—>NewGlobalRef()函数声明其是一个全局引用的话,在运行的时候可能就会报错:JNI ERROR (app bug): accessed stale local reference 0x5900021;表明在Jvm中该对象已经被回收了,引用已经失效了。而NewGlobalRef的作用就在于告诉JVM,C++中一直持有该引用,请不要回收。显然这又引发了另外一个问题,你需要在你不需要该引用的时候告诉JVM,那么就需要调用env->DelGlobalRef()。当然你也可以不调用,那么该Java对象将在你的程序关闭的时候被回收。

测试结果:

<code class="hljs http has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 5000s waste 3ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 5000s waste 18ms</span>

<span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 10000s waste 5ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 10000s waste 24ms</span>

<span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 50000s waste 44ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 50000s waste 121ms</span>

<span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 100000s waste 65ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 100000s waste 259ms</span></span></span></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

这次的结果表明,如果缓存方法ID和jclass能缩短一半的时间。但仍然不如Java快。这也很好理解,C++创建Java对象最终还是通过Java创建的,反复的通过反射去创建自然不如自身创建来得快。

总结

  • JNI中想访问Java Object方法签名、类名和变量名十分重要,一旦确定了就不要轻易单方面修改Java中的定义。因为这会导致JNI找不到相关的方法或类等,而引发JNI错误。
  • 虽然JNI提供了各种方法来完成Java的反射操作,但是请酌情使用,因为这会让Java代码与C++代码之间过度依赖。
  • 当你需要返回C++中的结构体数据的时候,可以考虑把结构体转换成对应的Java对象返回。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值