Jni基础(二) C语言访问Java构造方法,父类方法

来源:互联网 发布:同比环比数据分析 编辑:程序博客网 时间:2024/06/11 23:49
本篇主要介绍一下在jni开发中,C语言如何访问Java的构造函数,父类方法。

1.C语言访问Java构造函数
   试想一下这样的场景,当C语言能够访问Java的构造方法时,我们是不是就可以创建一个该类的对象。有了对象那我们就可以随意的调用该类的方法了。是不是很6。

Java代码:
public class JniTest { //访问Date类的构造函数    public native Date accessConstructor();//加载动态库    static{        System.loadLibrary("libjnitest");    } public static void main(String[] args) {           JniTest test=new JniTest();          Date date = test.accessConstructor();          SimpleDateFormat format=new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");                                       String formatDate = format.format(date);     System.out.println("当前日期:"+formatDate);    }}
C代码:
//访问date类的构造函数JNIEXPORT jobject JNICALL Java_JniExamp_JniTest_accessConstructor  (JNIEnv *env, jobject jobj){       jclass cls=(*env)->FindClass(env,"java/util/Date");       //获取构造方法的id       jmethodID constructor_mid=(*env)->GetMethodID(env,cls,"<init>","()V");       //实例化一个date对象      jobject date_obj= (*env)->NewObject(env,cls,constructor_mid);      //获取getTime的方法ID      jmethodID mid=(*env)->GetMethodID(env,cls,"getTime","()J");      //调用getTime方法      jlong time=(*env)->CallLongMethod(env,date_obj,mid);      printf("currenttime:%ld",time);       return date_obj;}


输出结果:


代码讲解:
在第二步中获取构造方法id的时候需要传入一个“<init>”,代表获取的是一个构造函数id
第三步实例化一个对象,使用的是NewObject方法 该方法能获取一个指定构造函数ID的Java对象

我们只是示例了一个访问空参构造函数,如果访问的是带参的构造函数,那么在实例化一个date对象的时候,要把相应参数传递进去。
2.访问父类方法:
为了更好的说明这个示例我们写了一个父类(Animal),他有一个方法shout,表明动物叫和这个动作
public class Animal {  public void shout(){        System.out.println("动物各种叫声。。。。。");    }}


子类 Dog它继承Animal并且重写了父类方法shout()
public class Dog extends Animal{  public void shout() {        System.out.println("小狗汪汪叫。。。。。");    }}


我们在主函数中这样实现一把:
public class JniTest {    public Animal animal=new Dog();   //访问父类方法    public native void accessParentMethod();    static{        System.loadLibrary("libjnitest");    }  public static void main(String[] args) {        JniTest test=new JniTest();       test.accessParentMethod();    }}


C代码实现:
//访问父类中的方法JNIEXPORT void JNICALL Java_JniExamp_JniTest_accessParentMethod  (JNIEnv *env, jobject jobj){    //获取到jclss    jclass cls=(*env)->GetObjectClass(env,jobj);    //获取属性id    jfieldID fid=(*env)->GetFieldID(env,cls,"animal","LJniExamp/Animal;");    //获取属性对象    jobject animal_obj=(*env)->GetObjectField(env,jobj,fid);    //获取Animal类的jclass    jclass animal_cls=(*env)->FindClass(env,"JniExamp/Animal");    //获取animal中的方法ID    jmethodID mid=(*env)->GetMethodID(env,animal_cls,"shout","()V");    //调用了父类中的方法 (*env)->CallNonvirtualObjectMethod(env,animal_obj,animal_cls,mid);}


运行结果


代码讲解:
这段c代码实现的时候先是获取了一个属性对象animal,对应的就是 public Animal animal=new Dog();这一段Java代码
获取这个属性id后,根据这个属性id获取到了他的属性对象,animal_obj。对个对象对应的是Dog,所以如果使用这个属性对象调用shout()方法的时候,按照常规调用CallObjectMethod 执行的结果应该是子类dog中的shout()  小狗汪汪叫。。。。。   
但我们需要访问的是小狗的父类Animal ,所以C语言又给我提供了方法CallNonvirtual<type>Method方法可以直接访问父类中的方法。
0 0
原创粉丝点击