`

本地方法取得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解析wsdl文档获取具体的方法与参数

    5. **调用方法**:现在,你可以通过这个代理对象来调用WSDL中定义的方法,并传入相应的参数。 ```java String response = port.sayHello("World"); System.out.println(response); ``` 在处理WSDL文档时,还可以...

    从网路取得图片 JAVA源码

    这个"从网络取得图片 JAVA源码"的示例提供了如何使用Java实现这一功能的具体步骤和代码实现。下面我们将深入探讨相关知识点。 首先,我们需要了解Java中的网络编程基础。Java提供了丰富的类库来支持网络编程,其中`...

    Java从网络取得文件Demo源码.zip

    这个"Java从网络取得文件Demo源码.zip"压缩包包含了一个示例项目,展示了如何使用Java实现这一功能。下面我们将深入探讨相关的Java知识点。 1. **URL类**:在Java中,`java.net.URL`类用于表示统一资源定位符,它是...

    JDK15java虚拟机规范

    运行时数据区域包括PC寄存器、Java虚拟机栈、堆、方法区、运行时常量池和本地方法栈。PC寄存器存储下一条将要执行的指令地址。Java虚拟机栈存储局部变量和方法的调用信息。堆是运行时数据区,存储所有对象的实例。...

    基础的java教程 Java学习资料

    5. JNI(Java Native Interface):允许Java代码调用本地(非Java)代码 本教程的"se-master"可能是指Java SE(Standard Edition)的项目或课程资料,涵盖以上知识点,通过实践练习和项目开发,你可以深入理解并...

    JAVA笔试题-包含JAVA各个方面的笔试题

    10. **JVM**:了解Java虚拟机的工作原理,包括类加载机制、内存模型(堆、栈、方法区、本地方法栈)以及JVM调优。 11. **设计模式**:掌握常用的设计模式,如单例模式、工厂模式、装饰器模式、观察者模式等,以及...

    21天java学习PPT

    16. **JNI(Java Native Interface)**:Java与C/C++交互的机制,如何编写和使用本地方法。 17. **注解(Annotation)**:注解的定义,元注解,以及如何使用注解自定义注解处理器。 18. **Swing GUI编程**:创建...

    java笔试题目及答案

    - **继承**:Java支持单一继承,子类可以继承父类的属性和方法,增强了代码复用。 - **多态**:通过接口或抽象类实现,允许不同类的对象对同一消息作出响应。 3. **异常处理** - **异常分类**:异常分为检查型...

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

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

    基于Java的从网络取得文件.zip

    4. 打开输入流:通过调用`getInputStream()`方法,我们可以获取到一个`InputStream`,用于读取网络上的数据。 ```java InputStream in = connection.getInputStream(); ``` 5. 读取并保存文件:使用`...

    Java热门面试题、Java面试指南

    - **本地方法栈**服务于Java本地接口,为每个线程存储本地方法信息。 2. **Java对象和类的方法**: - `Object`类提供了如`clone()`、`equals()`、`hashCode()`、`wait()`、`notify()`、`notifyAll()`、`finalize...

    java基础面试题汇总,通过代码的方式理解面试题.zip

    2. 封装、继承和多态:封装是将数据和方法结合在一起,继承允许子类继承父类的属性和行为,多态则允许使用一个接口调用不同类的方法。 二、Java语法 1. 变量与数据类型:Java有基本数据类型(如int、double等)和...

    Java开发程面试必备

    7. **反射**:理解Java反射机制,能够动态加载类、创建对象、调用方法,以及获取类的属性和方法信息。 8. **泛型**:了解泛型的基本概念和使用,如何避免类型转换错误,以及泛型通配符和边界等高级用法。 9. **JVM...

    Java华为笔试题,Java常见笔试题

    你需要知道JVM的内存模型(如堆、栈、方法区、本地方法栈和程序计数器),以及垃圾回收的工作原理(如分代收集、可达性分析和引用类型)。 以上就是Java华为笔试题可能涉及的主要知识点。在准备过程中,除了理论...

    java-test.zip_java笔试题_java面试题_site:www.pudn.com

    8. **反射**:知道如何使用Class类加载类,创建对象,调用方法,访问私有属性,以及动态代理。 9. **泛型**:理解泛型的基本概念,类型参数,通配符,以及在类、接口、方法、集合中的应用。 10. **Java 8及更高...

    Prentice Hall - Core Java 2 Vol2 ed5 ~.pdf

    10. **本地方法**:介绍了如何在Java程序中调用本地代码(通常是C/C++编写的),包括JNI(Java Native Interface)的使用方法。这对于实现高性能计算任务或访问特定硬件设备非常有用。 11. **XML与Java**:新增的...

    CCF历年真题(Java)(100分)

    【标题】"CCF历年真题(Java)(100分)" 指的是中国计算机学会(CCF)组织的计算机资格认证考试中,关于Java编程语言的历年试题集,这些试题集在测试用例中均取得了满分100分的成绩。这通常意味着这些题目代表了高...

    2020年-银盛支付-Java中级.pdf

    在Spring Cloud中,Feign用于简化服务之间的调用,它通过注解和动态代理,使得开发者无需关注HTTP请求的细节,就像调用本地方法一样调用远程服务。 3. **Eureka心跳机制** Eureka客户端默认每30秒向Eureka服务端...

    2019年秋季学期-Java应用与开发-复习提纲1

    11. **虚方法调用**:在Java中,通过父类引用调用子类重写的方法时,如果方法是非final或非static的,就可能发生虚方法调用。 12. **造型(类型转换)**:造型允许在兼容类型之间进行转换,分为自动造型和强制造型...

    java面试,考试java面试题大全

    5. **JVM内存模型**:理解堆内存、栈内存、方法区、本地方法栈和程序计数器的作用,以及垃圾回收机制(GC)的基本原理。 6. **多线程**:知道如何创建和管理线程,包括Thread类和Runnable接口,以及线程同步机制如...

Global site tag (gtag.js) - Google Analytics