美文网首页
jni反射java方法

jni反射java方法

作者: leaflying | 来源:发表于2020-12-24 13:19 被阅读0次

在我们写Android代码时,调用一个类中没有公开的方法,可以进行反射调用,而JNI开发中C++调用java的方法也是反射调用。下面我们就了解一下通过jni中的c++调用java中的方法。

1.类似于我们java中进行反射调用一下,我们得拿到我们的字节码对象
2.通过字节码对象找到方法对象
3.通过对象调用方法,可以调用空参数方法,也可以调用有参数方法,并且将参数通过调用的方法传入,(这里需要将参数变成java对象后才能传入,比如说如果我们要传递一个char *,那么我们需要把它转化为jstring对象)

基本数据类型对应表

Java类型 本地类型 描述
boolean jboolean C/C++8位整型
byte jbyte C/C++带符号的8位整型
char jchar C/C++无符号的16位整型
short jshort C/C++带符号的16位整型
int jint C/C++带符号的32位整型
long jlong C/C++带符号的64位整型
float jfloat C/C++32位浮点型
double jdouble C/C++64位浮点型
Object jobject 任何Java对象,或者没有对应java类型的对象
Class jclass Class对象
String jstring 字符串对象
Object[] jobjectArray 任何对象的数组
boolean[] jbooleanArray 布尔型数组
byte[] jbyteArray 比特型数组
char[] jcharArray 字符型数组
short[] jshortArray 短整型数组
int[] jintArray 整型数组
long[] jlongArray 长整型数组
float[] jfloatArray 浮点型数组
double[] jdoubleArray 双浮点型数组

下面我们就开始写代码,首先拿class对象

//可以通过传入全类名进行查找,注意这里需要把.替换成/
jclass _jclass = env->FindClass("com/test/ndktestapplication/TestBean");

//也可以在已有的对象中获取class对象
jclass _jclass = env -> GetObjectClass(test_bean);

然后我们通过class对象获取到方法ID,这里我们通过GetMethodID这个方法去获取,这里有三个参数 :第1个参数:Java类对象;第2个参数:方法名;第3个参数:该方法的签名。关于方法签名,下面提供一份表格。

Java类型 签名
boolean Z
short S
float F
byte B
int I
double D
char C
long J
void V
引用类型 L + 全限定名 + ;
数组 [+类型签名
//获取构造方法的方法ID,注意构造方法的方法名是"<init>"
jmethodID method_id = env->GetMethodID(_jclass, "<init>","()V");
//获取普通方法的方法ID,注意"()"中是传入参数的参数类型,外面是返回值的类型
jmethodID set_age_id = env->GetMethodID(_jclass,"setAge", "(I)V");

然后调用方法

    jclass _jclass = env->FindClass("com/test/ndktestapplication/TestBean");

    jmethodID method_id = env->GetMethodID(_jclass, "<init>","()V");

    #调用构造方法创建对象
    jobject o = env->NewObject(_jclass, method_id);

    jmethodID set_name_id = env->GetMethodID(_jclass,"setName", "(Ljava/lang/String;)V");
    env->CallVoidMethod(o,set_name_id,name_);

    jmethodID set_age_id = env->GetMethodID(_jclass,"setAge", "(I)V");
    env->CallVoidMethod(o,set_age_id,age);

    env -> ReleaseStringUTFChars(name_,name);
    env -> DeleteLocalRef(_jclass);

上面使用的java类

public class TestBean {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

如果java对象是通过java传递过来的,那么我们可以这么使用

    jclass _jclass = env -> GetObjectClass(test_bean);

    jmethodID get_name_id = env->GetMethodID(_jclass, "getName","()Ljava/lang/String;");
    jstring s = static_cast<jstring>(env->CallObjectMethod(test_bean, get_name_id));

    const char* name = env->GetStringUTFChars(s,0);

这里需要我们注意的是,所有我们在这里创建的对象,如果不返回java,必须用release掉,否则内存泄露。包括NewStringUTF,NewObject。如果返回java不必release,java会自己回收。

相关文章

  • jni反射java方法

    在我们写Android代码时,调用一个类中没有公开的方法,可以进行反射调用,而JNI开发中C++调用java的方法...

  • Android Review

    java相关 java基础面试题 四种引用对比 List,Set,Map 详解 反射 JNI JNI 各版本特性 ...

  • C、C++、Java?Java Native Interface

    C、C++、Java?Java Native Interface(JNI)特辑——C反射java函数 排版不佳建议...

  • Android JNI学习手册

    一、JNI基础学习-JNI调用java原生方法 JNI调用java原生方法有四个重要的东西 一、class 类信息...

  • Jni多线程与类加载

    在JNI中我们可以通过JNIEnv的FindClass方法查找到java的类然后进行类似反射的调用。 如果通过ja...

  • JNI 的简介与实现

    JNI简企 JNI Java Native Interface) ,即Java木地接口,是为java编写本地方法和...

  • JNI回调Java

    jclass、jobject、jmethodID 和 jfieldID jni回调java是通过反射来实现的,这些...

  • java JNI(java 调用c语言程序)

    JNI 简介 JNI 即Java Native Interface,说通俗点就是java端写一个nvtive方法,...

  • JNI基础(8): JNI调用Java方法

    8.1 JNI调用Java类的成员方法和静态方法 首先需要了解一下java方法在jni中签名格式。简单来说: (参...

  • JNI开发学习之C反射调用java方法

    前面记录了调用C的学习笔记,现在来记录一下C反射调用Java的笔记。JNI开发学习之调用C方法 Android开...

网友评论

      本文标题:jni反射java方法

      本文链接:https://www.haomeiwen.com/subject/ndkmnktx.html