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

本篇主要介绍一下在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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值