`

本地方法取得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 代码部分:

  1. packagecn.itcast;
  2. importjava.util.Date;
  3. publicclassTestNative{
  4. publicnativevoidsayHello();
  5. publicintnumber=10;
  6. publicstaticvoidmain(String[]args){
  7. System.loadLibrary("nativeCode");//Java类
  8. 中加载DLL,然后调用声明的native方法
  9. TestNativetst=newTestNative();
  10. tst.sayHello();
  11. System.out.println(tst.number);
  12. }
  13. }

b C++源码部分

  1. #include"cn_itcast_TestNative.h"
  2. #include<iostream>
  3. usingnamespacestd;
  4. JNIEXPORTvoidJNICALLJava_cn_itcast_TestNative_sayHello
  5. (JNIEnv*env,jobjectobj){
  6. //cout<<"Hello!"<<endl;
  7. //取得number属性值
  8. jclassclazz_TestNative=env->GetObjectClass(obj);
  9. jfieldIDid_number=env->GetFieldID
  10. (clazz_TestNative,"number","I");
  11. jintnumber=env->GetIntField(obj,id_number);
  12. cout<<number<<endl;//打印属性值
  13. //修改属性值
  14. env->SetIntField(obj,id_number,100L);
  15. }


(二)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代码部分

  1. packagecn.itcast;
  2. importjava.util.Date;
  3. publicclassTestNative{
  4. publicnativevoidsayHello();
  5. doublemax(doublenum1,doublenum2){
  6. returnnum1>num2?num1:num2;
  7. }
  8. publicstaticvoidmain(String[]args){
  9. System.loadLibrary("nativeCode");//Java类
  10. 中加载DLL,然后调用声明的native方法
  11. TestNativetst=newTestNative();
  12. tst.sayHello();
  13. }
  14. }

b C++源码部分

  1. #include"cn_itcast_TestNative.h"
  2. #include<iostream>
  3. usingnamespacestd;
  4. JNIEXPORTvoidJNICALLJava_cn_itcast_TestNative_sayHello
  5. (JNIEnv*env,jobjectobj){
  6. //取得number属性值
  7. jclassclazz_TestNative=env->GetObjectClass(obj);
  8. jmethodIDid_max=env->GetMethodID
  9. (clazz_TestNative,"max","(DD)D");
  10. jdoublemaxvalue=env->CallDoubleMethod(obj,
  11. id_max,3.14,3.15);
  12. cout<<maxvalue<<endl;
  13. }

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类

  1. packagecn.itcast;
  2. publicclassFather{
  3. publicvoidfunction(){
  4. System.out.println("Father:function");
  5. }
  6. }

(2)新增Child类

  1. packagecn.itcast;
  2. publicclassChildextendsFather{
  3. publicvoidfunction(){
  4. System.out.println("Child:function");
  5. }
  6. }

(3)java代码部分

  1. packagecn.itcast;
  2. importjava.util.Date;
  3. publicclassTestNative{
  4. publicnativevoidsayHello();
  5. publicFatherp=newChild();
  6. publicstaticvoidmain(String[]args){
  7. System.loadLibrary("nativeCode");//Java类
  8. 中加载DLL,然后调用声明的native方法
  9. TestNativetst=newTestNative();
  10. tst.sayHello();
  11. }
  12. }

(4)C++源码部分
  1. #include"cn_itcast_TestNative.h"
  2. #include<iostream>
  3. usingnamespacestd;
  4. JNIEXPORTvoidJNICALLJava_cn_itcast_TestNative_sayHello
  5. (JNIEnv*env,jobjectobj){
  6. jfieldIDid_p=env->GetFieldID
  7. (clazz_TestNative,"p","Lcn/itcast/Father;");
  8. jobjectp=env->GetObjectField(obj,id_p);//取得属性
  9. jclassclazz_Father=env->FindClass
  10. ("cn/itcast/Father");//找到Father类
  11. jmethodIDid_Father_function=env->GetMethodID
  12. (clazz_Father,"function","()V");//获取Father类里面方法的ID
  13. //调用方法,取得的是子类方法
  14. env->CallVoidMethod(p,id_Father_function);
  15. //相当于如下java代码
  16. //Fatherp=tst.p;
  17. //p.function();
  18. env->CallNonvirtualVoidMethod
  19. (p,clazz_Father,id_Father_function);//调用父类方法
  20. }

分享到:
评论

相关推荐

    JAVA上百实例源码以及开源项目源代码

    6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用...

    JAVA上百实例源码以及开源项目

    6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用...

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    8.3.2 开发本地调用的无状态 Session Bean 311 8.4 发布Session Bean 314 8.4.1 打包EJB-JAR 315 8.4.2 Annotation与部署描述文件 315 8.5 开发有状态的Session Bean 318 8.6 Session Bean的生命周期 321 8.6.1 无...

    java面试宝典

    21、当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 10 22、我们在web 应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,...

    基于java的音乐播放器课程设计报告.doc

    Java课程设计报告 题目:java音乐...找到设备的位置以后,调用ManageCreatePlayer方法创建Player,当Playe r开始播放的时候,就开始了捕获的过程。 有多种方法获得捕获设备信息,可以通过查询指定的格式,也可以查询特

    千方百计笔试题大全

    21、当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 10 22、我们在web 应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,...

    ssh(structs,spring,hibernate)框架中的上传下载

     此外lazy="true"说明地返回整个Tfile对象时,并不返回fileContent这个字段的数据,只有在显式调用tfile.getFileContent()方法时才真正从数据库中获取fileContent的数据。这是Hibernate3引入的新特性,对于包含重量...

    J2EE中文版指南 CHM格式 带全文检索

    四 RosterApp中的方法调用 110 “新建”一个运动员 110 将运动员加入组 111 “删除”一个运动员 112 从组中开除运动员 112 获得一个组里的所有运动员 113 获取组成员的副本 114 根据位置查询运动员 116 查询运动员的...

    新版Android开发教程.rar

    � Google 提供了一套 Java 核心包 (J2SE 5,J2SE 6) 的有限子集,尚不承诺遵守 Java 任何 Java 规范 , 可能会造 成J ava 阵营的进一步分裂。 � 现有应用完善度不太够,需要的开发工作量较大。--------------------...

    PL/SQL 基础.doc

    4) SQLJ: 很新的一种用Java访问Oracle数据库的方法,会的人不多; 5) JDBC 6) PL/SQL: 存储在数据库内运行, 其他方法为在数据库外对数据库访问,只适合ORACLE; 2. PL/SQL 1) PL/SQL(Procedual language/SQL)...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    本人声明所呈交的学位论文是我个人在导师指导下进行的研究工作及取得的研究成果。尽我所知,除了文中特别加以标注和致谢的地方外,论文中不包含其他人已经发表或撰写过的研究成果,也不包含为获得东南大学或其它教育...

    Visual C++ 2010入门经典(第5版)--源代码及课后练习答案

     Ivor Horton是撰著Java、C和C++编程语言图书的杰出作家之一。大家一致认为,他的著作独具风格,无论是编程新手,还是经验丰富的编程人员,都很容易理解其内容。在个人实践中,Ivor Horton也是一名系统顾问。他从事...

    Struts2 in action中文版

    15.2 动态方法调用 310 15.2.1 通配符方法的选择 310 15.2.2 动态工作流 312 15.3 使用令牌防止表单重复提交 313 15.3.1 使用s:token/表单标签 313 15.3.2 令牌拦截器规则的例外 314 15.4 自动显示等待页面 316 15.5...

    ZendFramework中文文档

    4.2.1. Zend_Cache 工厂方法 4.2.2. 标记纪录 4.2.3. 缓存清理 4.3. Zend_Cache前端 4.3.1. Zend_Cache_Core 4.3.1.1. 简介 4.3.1.2. 可用选项 4.3.1.3. 例子 4.3.2. Zend_Cache_Frontend_Output 4.3.2.1. ...

    Visual C++ 2005入门经典--源代码及课后练习答案

    本书延续了Ivor Horton讲解编程语言的独特方法,从中读者可以学习Visual C++ 2005的基础知识,并全面掌握在MFC和Windows Forms中访问数据源的技术。此外,本书各章后面的习题将有助于读者温故而知新,并尽快成为C++...

    Oracle SQL高级编程(资深Oracle专家力作,OakTable团队推荐)--随书源代码

    2.12 执行计划并取得数据行 50 2.13 SQL执行——总览 52 2.14 小结 53 第3章 访问和联结方法 55 3.1 全扫描访问方法 55 3.1.1 如何选择全扫描操作 56 3.1.2 全扫描与舍弃 59 3.1.3 全扫描与多块读取 60 ...

    C#微软培训资料

    18.2 在 C #代码中调用 C++和 VB 编写的组件 .240 18.3 版 本 控 制 .249 18.4 代 码 优 化 .252 18.5 小 结 .254 第五部分 附 录 .255 附录 A 关 键 字.255 附录 B 错 误 码.256 附录 C .Net 名字空间...

    华为编程开发规范与案例

    在新的编程思想中,指针基本上被禁止使用(JAVA中就是这样),至少也是被限制使用。而在我们交换机的程序中大量使用指针,并且有增无减。 2、防止指针/数组操作越界 【案例1.2.1】 在香港项目测试中,发现ISDN话机...

Global site tag (gtag.js) - Google Analytics