传递和使用Java对象

在前例中,我们将一个字串传递给固有方法。事实上,亦可将自己创建的Java对象传递给固有方法。
在我们的固有方法内部,可访问已收到的那些对象的字段及方法。
为传递对象,声明固有方法时要采用原始的Java语法。如下例所示,MyJavaClass有一个public(公共)字段,以及一个public方法。UseObjects类声明了一个固有方法,用于接收MyJavaClass类的一个对象。为调查固有方法是否能控制自己的自变量,我们设置了自变量的public字段,调用固有方法,然后打印出public字段的值。
 

class MyJavaClass {
  public void divByTwo() { aValue /= 2; }
  public int aValue;
}

public class UseObjects {
  public static void main(String [] args) {
    UseObjects app = new UseObjects();
    MyJavaClass anObj = new MyJavaClass();
    anObj.aValue = 2;
    app.changeObject(anObj);
    System.out.println("Java: " + anObj.aValue);
  }
  private native void
  changeObject(MyJavaClass obj);
  static {
    System.loadLibrary("UseObjImpl");
  }
}

编译好代码,并将.class文件传递给javah后,就可以实现固有方法。在下面这个例子中,一旦取得字段和方法ID,就会通过JNI函数访问它们。
 

JNIEXPORT void JNICALL
Java_UseObjects_changeObject(
  JNIEnv * env, jobject jThis, jobject obj) {
  jclass cls;
  jfieldID fid;
  jmethodID mid;
  int value;
  cls = env->GetObjectClass(obj);
  fid = env->GetFieldID(cls,
        "aValue", "I");
  mid = env->GetMethodID(cls,
        "divByTwo", "()V");
  value = env->GetIntField(obj, fid);
  printf("Native: %d\n", value);
  env->SetIntField(obj, fid, 6);
  env->CallVoidMethod(obj, mid);
  value = env->GetIntField(obj, fid);
  printf("Native: %d\n", value);
}

除第一个自变量外,C++函数会接收一个jobject,它代表Java对象引用“固有”的那一面——那个引用是我们从Java代码里传递的。我们简单地读取aValue,把它打印出来,改变这个值,调用对象的divByTwo()方法,再将值重新打印一遍。
为访问一个字段或方法,首先必须获取它的标识符。利用适当的JNI函数,可方便地取得类对象、元素名以及签名信息。这些函数会返回一个标识符,利用它可访问对应的元素。尽管这一方式显得有些曲折,但我们的固有方法确实对Java对象的内部布局一无所知。因此,它必须通过由JVM返回的索引访问字段和方法。这样一来,不同的JVM就可实现不同的内部对象布局,同时不会对固有方法造成影响。
若运行Java程序,就会发现从Java那一侧传来的对象是由我们的固有方法处理的。但传递的到底是什么呢?是指针,还是Java引用?而且垃圾收集器在固有方法调用期间又在做什么呢?
垃圾收集器会在固有方法执行期间持续运行,但在一次固有方法调用期间,我们的对象可保证不会被当作“垃圾”收集去。为确保这一点,事先创建了“局部引用”,并在固有方法调用之后立即清除。由于它们的“生命期”与调用过程息息相关,所以能够保证对象在固有方法调用期间的有效性。
由于这些引用会在每次函数调用的时候创建和破坏,所以不可在static变量中制作固有方法的局部副本(本地拷贝)。若希望一个引用在函数存在期间持续有效,就需要一个全局引用。全局引用不是由JVM创建的,但通过调用特定的JNI函数,程序员可将局部引用扩展为全局引用。创建一个全局引用时,需对引用对象的“生存时间”负责。全局引用(以及它引用的对象)会一直留在内存里,直到用特定的JNI函数明确释放了这个引用。它类似于C的malloc()和free()。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索对象
, 函数
, 方法
, public
, 字段
, jobject
, 全局变量java
一个
java对象作为参数传递、java对象引用传递、java 对象传递、java对象参数传递、java对象值传递,以便于您获取更多的相关知识。

时间: 2024-11-16 10:28:33

传递和使用Java对象的相关文章

自定义对象 xfire-用spring整合xfire时传递自定义类型的对象时报空指针错误

问题描述 用spring整合xfire时传递自定义类型的对象时报空指针错误 Exception in thread ""main"" org.codehaus.xfire.fault.XFireFault: Fault: java.lang.NullPointerException at org.codehaus.xfire.fault.XFireFault.createFault(XFireFault.java:89) at org.codehaus.xfire.

Ajax 的 Java 对象序列化

ajax|对象 如果您正在使用异步 JavaScript 和 XML(Ajax)进行 Java Web 开发,那么您最关心的问题可能就是把数据从服务器传递给客户机.在面向 Java 开发人员的 Ajax 系列的文章中,Philip McCarthy 介绍了 Java 对象序列化的五种方式,并提供了选择最适合应用程序的数据格式和技术所需要的全部信息.本文将侧重于许多 Java Web 开发人员最关心的问题:为客户机生成数据. 多数 Java 开发人员已经把模型-视图-控制器(MVC)模式应用在他们

Ajax 的 Java 对象序列化(1)

ajax|对象 如果您正在使用异步 JavaScript 和 XML(Ajax)进行 Java Web 开发,那么您最关心的问题可能就是把数据从服务器传递给客户机. 在面向 Java 开发人员的 Ajax 系列的文章中,Philip McCarthy 介绍了 Java 对象序列化的五种方式,并提供了选择最适合应用程序的数据格式和技术所需要的全部信息.本文将侧重于许多 Java Web 开发人员最关心的问题:为客户机生成数据. 多数 Java 开发人员已经把模型-视图-控制器(MVC)模式应用在他

面向Java开发人员的Ajax:Java对象序列化(1)

ajax|java对象 本文我们讨论 Ajax 开发的基础知识,但是将侧重于许多 Java Web 开发人员最关心的问题:为客户机生成数据. 多数 Java 开发人员已经把模型-视图-控制器(MVC)模式应用在他们的 Web 应用程序上.在传统的 Web 应用程序中,视图组件由 JSP 或者其他表示技术(例如 Velocity 模板)构成. 这些表示组件动态地生成全新的 HTML 页面,替代用户以前正在查看的页面,从而更新用户界面.但是,在 Java Web 应用程序使用 Ajax UI 的情况

java对象序列化学习笔记

java对象|笔记 目前网络上关于对象序列化的文章不少,但是我发现详细叙述用法和原理的文章太少.本人把自己经过经验总结和实际运用中的体会写成的学习笔记贡献给大家.希望能为整个java社区的繁荣做一点事情.    序列化的过程就是对象写入字节流和从字节流中读取对象.将对象状态转换成字节流之后,可以用java.io包中的各种字节流类将其保存到文件中,管道到另一线程中或通过网络连接将对象数据发送到另一主机.对象序列化功能非常简单.强大,在RMI.Socket.JMS.EJB都有应用.对象序列化问题在网

面向Java开发人员的Ajax: Ajax的Java对象序列化

在这个系列的 第一篇文章 中,我介绍了 Ajax 的构造块: 如何用 JavaScript XMLHttpRequest 对象从 Web 页面向服务器发送异步请求. 如何用 Java servlet 处理和响应请求(向客户机返回 XML 文档). 如何在客户端用响应文档更新页面视图. 这一次,我将继续讨论 Ajax 开发的基础知识,但是将侧重于许多 Java Web 开发人员最关心的问题:为客户机生成数据. 多数 Java 开发人员已经把模型-视图-控制器(MVC)模式应用在他们的 Web 应用

Java对象序列化使用基础

所谓对象序列化就是将对象的状态转换成字节流,以后可以通过这些值再生成相同状态的对象.这个过程也可以通过网络实现,可以先在Windows机器上创建一个对象,对其序列化,然后通过网络发给一台Unix机器,然后在那里准确无误地重新"装配".像RMI.Socket.JMS.EJB它们中的一种,彼此为什么能够传递Java对象,当然都是对象序列化机制的功劳. Java对象序列化机制一般来讲有两种用途: Java的JavaBeans: Bean的状态信息通常是在设计时配置的,Bean的状态信息必须被

对象内存分配-Java对象中的对象如何分配内存?

问题描述 Java对象中的对象如何分配内存? 在Java中,比如A a=new A ();是在堆内存中创建了一个对象,然后把这个对象的引用传递给栈内存中的对象变量a.那如果a对象拥有一个字符串对象,那a对象中保存的是这个字符串对象的引用吗? 解决方案 a是A类型的.不能拥有一个字符串对象. 如果A中有一个字符串字段,那一样的,堆上的a中存储着指向这个字符串的引用.字符串本身则放在常量池或者也在堆上. 解决方案二: 不知道是不是这个意思:将字符串对象符值给a,这是不可以的,除非是相同类型,如果A是

Json字符串转换为java对象的各种实现方法【json_lib框架、Gson、org.json】

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://mengzhengbin520.blog.51cto.com/7590564/1283361 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写.同时也易于机器解析和生成.它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - Decembe