本地方法取得Java属性/调用java方法

(一)取得Java属性/设定Java属性值

1.取得相应属性的jfieldID之后就可以用
Set<TYPE>Field();
Get<TYPE>Field();
SetStatic<TYPE>Field();
GetStatic<TYPE>Field();
等函数对java属性进行操作
b C++源码部分:

 


2.获取数组属性——>GetObjectField


3.例子:
a java 代码部分:

 

 

view plain copy to clipboard print ?
  1. package cn.itcast;  
  2.   
  3.   
  4.   
  5.   
  6. import java.util.Date;  
  7.   
  8. public class TestNative {  
  9.  public native void sayHello();  
  10.    
  11.  public int number = 10;  
  12.  public static void main(String[] args) {   
  13.    System.loadLibrary("nativeCode");//Java类  
  14.   
  15. 中加载DLL,然后调用声明的native方法  
  16.    TestNative tst=new TestNative();  
  17.    tst.sayHello();  
  18.    System.out.println(tst.number);  
  19.  }  
  20.   
  21. }  

 

b C++源码部分

 

view plain copy to clipboard print ?
  1. #include "cn_itcast_TestNative.h"  
  2. #include<iostream>  
  3. using namespace std;  
  4.   
  5.   
  6. JNIEXPORT void JNICALL Java_cn_itcast_TestNative_sayHello  
  7. (JNIEnv *env, jobject obj){  
  8.    // cout<<"Hello!"<<endl;  
  9.  //取得number属性值  
  10.  jclass clazz_TestNative = env->GetObjectClass(obj);  
  11.  jfieldID id_number = env->GetFieldID  
  12.   
  13. (clazz_TestNative,"number","I");  
  14.  jint number = env->GetIntField(obj,id_number);  
  15.   
  16.  cout<<number<<endl;//打印属性值  
  17.  //修改属性值  
  18.  env->SetIntField(obj,id_number,100L);  
  19. }  

 


(二)Java方法的调用

1.取得相应的jmethodID传入函数的参数中,就可以用
Call<TYPE>Method();
CallStatic<TYPE>Method();
CallNonvittual<TYPE>Method();
等函数对java函数进行调用
 


2.调用形式


java中方法:
boolean function(int i , bouble d , char c){
    ···
}


//env->CallBooleanMethod(obj , id_function, 100L, 3.44 , L'3');//第一种调用函数形式

 

 

//第二种调用形式

 

jvalue * args = new jvalue[3];//存储参数的数组
args[0].i=100L;
args[1].d=3.44;
args[2].c=L'3';

env->CallBooleanMethod(obj , id_function , args);
delete [] args;//删除内存

 

3.调用例子
a java代码部分

view plain copy to clipboard print ?
  1. package cn.itcast;  
  2.   
  3. import java.util.Date;  
  4.   
  5. public class TestNative {  
  6.  public native void sayHello();   
  7.  double max(double num1,double num2){  
  8.   return num1>num2?num1:num2;  
  9.  }  
  10.    
  11.  public static void main(String[] args) {   
  12.   System.loadLibrary("nativeCode");//Java类  
  13.   
  14. 中加载DLL,然后调用声明的native方法  
  15.   TestNative tst=new TestNative();  
  16.   tst.sayHello();  
  17.  }  
  18.   
  19. }  

b C++源码部分

 

 

view plain copy to clipboard print ?
  1. #include "cn_itcast_TestNative.h"  
  2. #include<iostream>  
  3. using namespace std;  
  4.   
  5.   
  6. JNIEXPORT void JNICALL Java_cn_itcast_TestNative_sayHello  
  7. (JNIEnv *env, jobject obj){  
  8.  //取得number属性值  
  9.  jclass clazz_TestNative = env->GetObjectClass(obj);  
  10.                  jmethodID id_max=env->GetMethodID  
  11.   
  12. (clazz_TestNative,"max","(DD)D");  
  13.  jdouble maxvalue=env->CallDoubleMethod(obj,   
  14.   
  15. id_max,3.14,3.15);  
  16.  cout<<maxvalue<<endl;  
  17.   
  18.   
  19. }  

 

 

 

 

 

3.CallNonvirtual<TYPE>Method
如下java代码:
第一段
public class Father{
    public void function(){
        System.out.println("Father:func");
    }
}

 

第二段
public class Child extends Father{
    public void function(){
        System.out.println("Child:func");
    }
}

问题:如果出现以下代码,问其是调用哪个方法?
Father p = new Child();
p.function();

如下C++代码:
第一段
class Father{
    public:
       virtual void function(){//若加上virtual又如何
       cout<<"Father:func"<<endl;
    }
}

第二段
class Child: public Father
    public: void function(){
        cout<<"Child:func"<<endl;
    }
}

问题:如果出现以下代码,问其是调用哪个成员函数?
Father* p = new Child();
p->function();

在JNI中定义的CallNonvirtual<TYPE>Method就能够对子类对象调

用父类方法的功能。如果想要调用一个对象的父类方法,而不是子类

的这个方法的话,就可以使用CallNonvirtual<TYPE>Method

使用方式:
首先取得父类及要调用的父类方法的jmethodID
然后传入到这个函数就能通过子类对象呼叫被覆写(override)的父

类的方法

使用实例
(1)新增Father类

view plain copy to clipboard print ?
  1. package cn.itcast;  
  2.   
  3. public class Father {  
  4.  public void function(){  
  5.   System.out.println("Father:function");  
  6.  }  
  7. }  

(2)新增Child类

 

view plain copy to clipboard print ?
  1. package cn.itcast;  
  2.   
  3. public class Child extends Father {  
  4.   
  5.  public void function() {  
  6.   System.out.println("Child:function");  
  7.  }      
  8. }  

(3)java代码部分

 

view plain copy to clipboard print ?
  1. package cn.itcast;  
  2. import java.util.Date;  
  3. public class TestNative {  
  4.  public native void sayHello();  
  5.  public Father p = new Child();   
  6.  public static void main(String[] args) {   
  7.   System.loadLibrary("nativeCode");//Java类  
  8.   
  9. 中加载DLL,然后调用声明的native方法  
  10.   TestNative tst=new TestNative();  
  11.   tst.sayHello();  
  12.  }  
  13. }  

(4)C++源码部分
view plain copy to clipboard print ?
  1. #include "cn_itcast_TestNative.h"  
  2. #include<iostream>  
  3. using namespace std;  
  4.   
  5.   
  6. JNIEXPORT void JNICALL Java_cn_itcast_TestNative_sayHello  
  7. (JNIEnv *env, jobject obj){  
  8.   
  9.  jfieldID id_p = env->GetFieldID  
  10.   
  11. (clazz_TestNative,"p","Lcn/itcast/Father;");  
  12.  jobject p = env->GetObjectField(obj,id_p);//取得属性  
  13.   
  14.  jclass clazz_Father = env->FindClass  
  15.   
  16. ("cn/itcast/Father");//找到Father类  
  17.  jmethodID id_Father_function = env->GetMethodID  
  18.   
  19. (clazz_Father,"function","()V");//获取Father类里面方法的ID  
  20.   
  21.     //调用方法,取得的是子类方法  
  22.     env->CallVoidMethod(p,id_Father_function);  
  23.   
  24.   
  25. //相当于如下java代码  
  26.  //Father p = tst.p;  
  27.  //p.function();  
  28.   
  29.  env->CallNonvirtualVoidMethod  
  30.   
  31. (p,clazz_Father,id_Father_function);//调用父类方法  
  32.   
  33. }  

 

你可能感兴趣的:(本地方法取得Java属性/调用java方法)