精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● Java>>JAVA编程>>网络编程>>RMI>>RMI规范--第七章(2)

主题:RMI规范--第七章(2)
发信人: daystream()
整理人: biubiu(2000-01-04 11:48:13), 站内信件
7.4 激活接口
在 RMI 激活协议中,为使系统运转正常,激活器必须保证以下两点:

象所有的系统守护进程一样,计算机处于打开状态时激活器必须保持运行状态 

激活器不能重新激活已处在活动状态的远程对象。 
激活器将为它所要激活的组和对象维护一个相应的信息数据库。

 

7.4.1 激活器接口 
激活器是参与激活进程的实体之一。如前所述,stub 内的不完善引用将通过调用
激活器的 activate 方法来获得对可激活远程对象的“活”引用。激活器接到激
活请求后,就开始查找该激活标识符 id 的激活描述符,以决定要在哪个组中激
活对象,然后调用激活组的实例化器的newInstance 方法(ActivationGroup 的
远程接口将在后面说明)。激活器将根据需要启动激活组的执行过程。例如,如
果给定的组描述符的激活组还未运行,则激活器将为该激活组生成一个子虚拟机
,以便在该新虚拟机中建立该组。

激活器将负责监控和检测激活组何时失败,以便将过时的远程引用从其内部表中
删去。

package java.rmi.activation;
public interface Activator extends java.rmi.Remote
{
java.rmi.MarshalledObject activate(ActivationID id,
  boolean force)
throws UnknownObjectException, ActivationException,
       java.rmi.RemoteException;
}


activate 方法激活与激活标识符 id 所关联的对象。如果激活器知道对象已经为
活动对象,且 force 参数为 false,就会立即将含有“活”引用的 stub 返给调
用程序;如果激活器不知道相应的远程对象是活动的或 force 参数为 true,则
激活器将利用激活描述符信息(先前已为获得 id 而注册过)来决定对象应该在
哪个组(虚拟机)中被激活。如果对象组的相应激活 Instantiator 已经存在,
则激活器将通过传递 id 和对象的激活描述符来调用该激活实例化器的newInsta
nce 方法。

如果对象组描述符的激活实例化器(组)还不存在,则激活器将启动新的 Activ
ationInstantiator 化身执行进程(例如通过生成子进程)。当激活器为某一组
重建 ActivationInstantiator 时,它必须将该组的化身数增一。注意,化身数
从 0 开始。激活系统用化身数来检测后来的 ActivationSystem.activeGroup 和
 ActivationMonitor.inactiveGroup 调用。激活系统将弃去那些化身数小于组的
当前数的调用。


----------------------------------------------------------------------
----------

注意 - 激活器在启动新的激活组时必须与激活组的标识符、描述符及化身数进行
通讯。激活器将在一个独立的虚拟机中(例如作为一个独立的进程或子进程)生
成激活组。因此,它必须将信息传递过去,以指定用 ActivationGroup.createG
roup 方法来创建该组时所需的信息。激活器并未指定如何将此信息传给所生成的
进程。可用已编组对象的形式将此信息送到子进程的标准输入中。 


----------------------------------------------------------------------
----------

当激活器接收到激活组的回调(通过 ActivationSystem.activeGroup 方法,该
回调可指明激活组的引用和化身数)时,激活器就可以调用该激活实例化器的 n
ewInstance 方法,从而将每个待定的激活请求转发给该激活实例化器,同时将结
果(一个已编组远程对象引用、一个 stub)返给每个调用程序。

注意,激活器接收的是 MarshalledObject 对象而不是 Remote 对象。因此,激
活器不需要加载该对象的代码,也不需要参与该对象的分布式垃圾收集。如果激
活器保留了对远程对象的强引用,则该激活器将防止该对象在正常的分布式垃圾
收集机制下被当作垃圾而收集。

如果激活失败,activate 方法将抛出 ActivationException。激活可能会因以下
各种原因而失败:找不到类、无法与激活组取得联系等。如果先前没有为激活标
识符 id 向该激活器注册激活描述符,则 activate 方法将抛出 UnknownObject
Exception。如果对该激活器的远程调用失败,则抛出 RemoteException。




7.4.2 ActivationSystem 接口 
ActivationSystem 提供了一种为组和可激活对象(这些对象将在这些组中被激活
)注册的方法。 ActivationSystem 与 Activator 和 ActivationMonitor 都能
密切合作。前者负责激活通过 ActivationSystem 所注册的对象;后者负责获取
活动对象、非活动对象及非活动组的有关信息。

package java.rmi.activation;
public interface ActivationSystem extends java.rmi.Remote
{
public static final int SYSTEM_PORT = 1098;

ActivationGroupID registerGroup(ActivationGroupDesc desc)
throws ActivationException, java.rmi.RemoteException;

ActivationMonitor activeGroup(ActivationGroupID id,
ActivationInstantiator group,
long incarnation)
throws UnknownGroupException, ActivationException,
   java.rmi.RemoteException;

void unregisterGroup(ActivationGroupID id)
throws ActivationException, UnknownGroupException,
   java.rmi.RemoteException;

ActivationID registerObject(ActivationDesc desc)
throws ActivationException, UnknownGroupException,
   java.rmi.RemoteException;

void unregisterObject(ActivationID id)
throws ActivationException, UnknownObjectException,
   java.rmi.RemoteException;

void shutdown() throws java.rmi.RemoteException;
}



----------------------------------------------------------------------
----------

注意 - 作为一种安全措施,以上所有方法(registerGroup、activeGroup、unr
egisterGroup、registerObject、unregisterObject 和 shutdown)如果被客户
机所调用,且该客户机所处主机与激活系统不同,则将抛出 java.rmi.AccessEx
ception。该异常是 java.rmi.RemoteException 的子类。


----------------------------------------------------------------------
----------

registerObject 方法用来注册激活描述符 desc,同时也为可激活远程对象获取
激活标识符。 ActivationSystem 为描述符 desc 所指定的对象创建 Activatio
nID(激活标识符),并将激活描述符及其关联的标识符记录在稳定的存储库中以
备将来使用。当 Activator 接到某个特定标识符的 activate 请求时,它就查找
该指定标识符的激活描述符(先前已注册),并用此信息来激活该对象。如果 d
esc 中所引用的组并没有向该系统注册,则该方法将抛出 UnknownGroupExcepti
on。如果注册失败(例如,数据库更新失败等),则抛出 ActivationException
。如果远程调用失败, 则抛出 RemoteException。

unregisterObject 方法用于删除激活标识符 id 及以前向 ActivationSystem 注
册过的相关描述符。该调用完成后,就不能再用对象的激活 id 来激活该对象。
如果对象的 id 是未知的(没有被注册),则该方法将抛出 UnknownObjectExce
ption。如果注销失败(例如,数据库的更新失败等),则该方法将抛出 Activa
tionException。如果远程调用失败,则抛出 RemoteException。

registerGroup 方法用于向激活系统注册组描述符 desc 所指定的激活组,并返
回指派给该组的 ActivationGroupID。必须先向 ActivationSystem 注册激活组
,然后才能在该组中注册对象。 如果组的注册失败,则该方法将抛出 Activati
onException。如果远程调用失败,则抛出 RemoteException。

activeGroup 方法是来自 ActivationGroup(具有标识符 id)的回调,用以通知
激活系统下列信息:组现在是活动的,而且也是该虚拟机的 ActivationInstant
iator。此回调是在 ActivationGroup.createGroup 方法内部进行的,可以获取
 ActivationMonitor。组将用该 ActivationMonitor 就对象和组的状态(即该组
内的组和对象已变为非活动的)对系统进行更新。 如果该组没有被注册,则抛出
 UnknownGroupException。如果该组已是活动的,则抛出 ActivationException
。如果对激活系统的远程调用失败,则抛出 RemoteException。

unregisterGroup 方法将具有标识符 id 的激活组从激活系统中删掉。激活组将
进行此回调,以通知激活器应该将该组销毁。如果此调用顺利完成,就将无法再
在该组内注册和激活对象。有关该组及其相关对象的所有信息都将从系统中删掉
。如果该组是未经注册的,则该方法将抛出 UnknownGroupException。如果远程
调用失败,则抛出 RemoteException。如果注销失败(如数据库更新失败等),
则抛出 ActivationException。

shutdown 方法将以适当的异步方式终止激活系统和所有有关的激活进程(激活器
、监控器及组)。由激活守护进程所生成的所有组都将被销毁,激活守护进程也
将退出。要关闭激活系统守护进程 rmid,请执行命令:

rmid -stop [-端口号]


该命令将关闭指定端口上的激活守护进程(如果没有指定端口,则将关闭缺省端
口上的守护进程)。

 

7.4.3 ActivationMonitor 类 
ActivationMonitor 是 ActivationGroup 特有的,它可通过调用 ActivationSy
stem.activeGroup 以报告某个组时获得(这种调用是在 ActivationGroup.crea
teGroup 方法内部进行的)。激活组在出现以下情况时负责通知 ActivationMon
itor:它的对象已变成活动对象、非活动对象或该组已整个变成非活动。

package java.rmi.activation;
public interface ActivationMonitor
extends java.rmi.Remote
{

public abstract void inactiveObject(ActivationID id)
throws UnknownObjectException, RemoteException;

public void activeObject(ActivationID id,
  java.rmi.MarshalledObject mobj)
throws UnknownObjectException, java.rmi.RemoteException;

public void inactiveGroup(ActivationGroupID id,
   long incarnation)
throws UnknownGroupException, java.rmi.RemoteException;
}


当激活组中的某个对象变成非活动(停用)时,该激活组将调用其监控器的 ina
ctiveObject 方法。激活组通过调用它的 inactiveObject 方法来发现其虚拟机
中的对象(该对象参与了激活)是否已为非活动状态。

inactiveObject 调用将通知 ActivationMonitor 其所保留的、具有激活标识符
 id 的对象的远程对象引用已不再有效。监控器将把与 id 关联的引用视为已过
时。由于该引用被当成过时引用,因此后面为同一激活标识符所进行的 activat
e 调用将导致远程对象被重新激活。如果该对象对 ActivationMonitor 未知,该
方法将抛出 UnknownObjectException。如果远程调用失败,则抛出 RemoteExce
ption。

activeObject 调用通知 ActivationMonitor 与 id 相关联的对象现在是活动的
。参数 obj 是该对象的 stub 的编组表述。 如果组中的某个对象是通过其它方
法被激活的,而不是由系统直接激活的(也就是说,对象被注册并自己“激活”
自己),则 ActivationGroup 必须通知其监控器。如果该对象的标识符先前没有
被注册,则该方法将抛出 UnknownObjectException。如果远程调用失败,则抛出
 RemoteException。

inactiveGroup 调用通知监控器由 id 和 incarnation 所指定的组现在已非活动
。一旦下一个要求在该组内激活对象的请求出现时,将用一个更大的化身数来重
新创建该组。当组中所有对象都报告说它们已非活动对象时,该组即变成非活动
组。如果该组的 id 没有被注册,或者化身数比该组当前的化身数更小,则该方
法将抛出 UnknownGroupException。如果远程调用失败,则抛出 RemoteExcepti
on。

 

7.4.4 ActivationInstantiator 类 
ActivationInstantiator 负责创建可激活对象的实例。ActivationGroup 的具体
子类实现 newInstance 方法,以便对在组内创建对象的过程进行控制。


package java.rmi.activation;
public interface ActivationInstantiator 
        extends java.rmi.Remote
{
        public MarshalledObject newInstance(ActivationID id,
                                                                      
                                     ActivationDesc desc)
                throws ActivationException, java.rmi.RemoteException;

                                                                      
          
}


为了在该组内重新创建具有激活标识符 id、描述符 desc 的对象,激活器需要调
用实例化器的 newInstance 方法。实例化器负责:

用描述符的 getClassName 方法来决定对象的类; 
从由描述符中所获得的 cadebase 路径中加载对象的类(用 getLocation 方法)
; 
通过调用对象的类的特殊“激活”构造函数创建该类的实例。这种特殊构造函数
带有两个参数:一个是对象的 ActivationID,另一个是含有对象特有的初始化数
据的 MarshalledObject; 
返回一个含有它所创建的远程对象的 MarshalledObject。 
实例化器还负责在它所创建或激活的对象不再是活动对象时进行报告,因此可以
对其 ActivationMonitor 执行相应的 inactiveObject 调用(详细信息,参见 
ActivationGroup 类)。

如果对象的激活失败, newInstance 方法将抛出 ActivationException。如果远
程调用失败,则该方法将抛出 RemoteException。

 

7.4.5 ActivationGroupDesc 类 
激活组描述符 ActivationGroupDesc 含有创建或重新创建激活组(将在该激活组
中激活相同 Java 虚拟机上的对象)所需的信息。

这种描述符含有:

组的类名, 
组的 cadebase 路径(组的类所在位置), 
“已编组”对象,它可包含对象特定的初始化数据。 
对象的类必须是 ActivationGroup 的具体子类。ActivationGroup 的子类是用 
ActivationGroup.createGroup 静态方法来创建或重新创建的,该静态方法将调
用含有以下两个参数的特殊构造函数: 

该组的 ActivationGroupID, 
该组的初始化数据(在 java.rmi.MarshalledObject 中) 
package java.rmi.activation;
public final class ActivationGroupDesc
implements java.io.Serializable
{

public ActivationGroupDesc(java.util.Properties props,
 CommandEnvironment env);;

public ActivationGroupDesc(String className,
 String codebase,
 java.rmi.MarshalledObject data,
 java.util.Properties props,
 CommandEnvironment env);

public String getClassName();

public String getLocation();

public java.rmi.MarshalledObject getData();

public CommandEnvironment getCommandEnvironment();

public java.util.Properties getPropertiesOverrides();

}
第一个构造函数将创建一个组描述符,它用系统的缺省值来作为组的实现和代码
位置。各属性指定了 Java 环境覆盖(它将覆盖组实现虚拟机中的系统属性)。
命令环境可控制启动子虚拟机时所用的确切命令/选项,也可为 null 以接受 rm
id 的缺省值。

第二个构造函数和第一个相同,但它允许指定 Properties 和 CommandEnvironm
ent。

getClassName 方法返回组的类名。

getLocation 方法返回 cadebase 路径,从中可加载该组的类。

getData 方法以编组形式返回组的初始化数据。

getCommandEnvironment 方法返回命令环境(可能为 null)。

getPropertiesOverrides 方法返回该描述符的属性覆盖(可能为 null)。

 

7.4.6 ActivationGroupDesc.CommandEnvironment 类 
CommandEnvironment 类允许对缺省系统属性进行覆盖,并可为 ActivationGrou
p 指定由实现所定义的选项。

public static class CommandEnvironment
implements java.io.Serializable
{
public CommandEnvironment(String cmdpath, String[] args);
public boolean equals(java.lang.Object);
public String[] getCommandOptions();
public String getCommandPath();
public int hashCode();


}
 

构造函数将用所给的命令 cmdpath 和另一个命令行选项 args 创建 CommandEnv
ironment。

equals 实现对命令环境对象的内容等效操作。对 hashCode 方法进行适当的实现
可在必要时将 CommandEnvironment 对象储存在散列表中。

getCommandOptions 方法返回环境对象的命令行选项。

getCommandPath 方法返回环境对象的命令字符串。

 

7.4.7 ActivationGroupID 类 
注册过的激活组的标识符可有以下几个用途:

在激活系统中对该组进行唯一标识 
含有对该组的激活系统的引用,因而必要时该组能与其激活系统联系。 
ActivationGroupID 将在调用 ActivationSystem.registerGroup 时被返回,并
用来在该激活系统内标识该组。当创建或重新创建激活组时,该组标识符将被作
为参数传给激活组的特殊构造函数。


package java.rmi.activation;
public class ActivationGroupID implements java.io.Serializable
{
public ActivationGroupID(ActivationSystem system);

public ActivationSystem getSystem();

public boolean equals(Object obj);

public int hashCode();
}

ActivationGroupID 构造函数创建唯一的组标识符。该标识符的 ActivationSys
tem 是 system。

getSystem 方法返回组的激活系统。

hashCode 方法返回组标识符的散列码。两个指向同一远程组的组标识符将具有相
同的散列码。

equals 方法比较两个组标识符内容的等效性。如果以下两个条件均成立,该方法
将返回 true: 1) 两个唯一标识符在内容上等价。2) 各标识符中指定的激活系
统都引用同一远程对象。

 

7.4.8 ActivationGroup 类 
ActivationGroup 负责在其组中创建“可激活”对象的新实例,并在出现下列情
况时通知其 ActivationMonitor: 其对象变成活动或非活动,或者该组整体变成
非活动。

ActivationGroup 最初是由以下方法之一创建的: 

作为创建对象的“缺省” ActivationDesc 的副效应而创建 
通过对 ActivationGroup.createGroup 方法的显式调用而创建 
作为在组(该组中仅 ActivationGroupDesc 被注册过)中激活第一个对象时的副
效应而创建。 
只有激活器才能重新创建 ActivationGroup。必要时,激活器将为每个已注册的
激活组生成一个独立的虚拟机(例如作为子进程)并将激活请求定向到相应的组
。生成虚拟机的方式与实现有关。激活组是通过 ActivationGroup.createGroup
 静态方法来创建的。createGroup 方法对即将创建的组有两个要求: 1) 该组必
须是 ActivationGroup 的具体子类;2) 该组必须有一个取以下两个参数的构造
函数: 

该组的 ActivationGroupID, 
该组的初始化数据(包含在 MarshalledObject中) 
创建完毕,ActivationGroup 的缺省实现将在创建该组的 ActivationGroupDesc
 时把系统属性设置为强制系统属性,并将安全管理器设置为 java.rmi.RMISecu
rityManager。如果应用程序要求当对象在组中被激活时设置某些特定的属性,则
该应用程序应在创建 ActivationDesc 之前(缺省 ActivationGroupDesc 创建前
)设置这些属性。

package java.rmi.activation;
public abstract class ActivationGroup
extends UnicastRemoteObject
implements ActivationInstantiator
{
protected ActivationGroup(ActivationGroupID groupID)
throws java.rmi.RemoteException;

public abstract MarshalledObject newInstance(ActivationID id,
            ActivationDesc desc)
throws ActivationException, java.rmi.RemoteException;

public abstract boolean inactiveObject(ActivationID id)
throws ActivationException, UnknownObjectException,
   java.rmi.RemoteException;

public static ActivationGroup createGroup(ActivationGroupID id,
      ActivationGroupDesc desc,
     long incarnation)
throws ActivationException;

public static ActivationGroupID currentGroupID();

public static void setSystem(ActivationSystem system)
throws ActivationException;

public static ActivationSystem getSystem()
throws ActivationException;

protected void activeObject(ActivationID id,
  java.rmi.MarshalledObject mobj)
throws ActivationException, UnknownObjectException,
   java.rmi.RemoteException;

protected void inactiveGroup()
throws UnknownGroupException, java.rmi.RemoteException;

}


激活器通过调用激活组的 newInstance 方法来激活具有激活描述符 desc 的对象
。激活组负责:

利用描述符的 getClassName 方法来确定该对象的类; 
通过 getLocation 方法从由描述符中所得到的 URL 路径中加载该类; 
通过调用该对象类的特殊构造函数来创建该类的实例。该构造函数取以下两个变
量:对象的 ActivationID 和含有对象初始化数据的 MarshalledObject; 
将刚创建的远程对象的序列化版本返给激活器。 
如果无法创建所给描述符的实例,该方法将抛出 ActivationException。

对该组的 inactiveObject 方法的调用是通过调用 Activatable.inactive 方法
来间接进行的。当远程对象停用时(该对象被认为非活动的),该对象的实现必
须调用 Activatable 的 inactive。如果对象在非活动时不调用 Activatable.i
nactive,则该对象将永远不会被作为垃圾收集,因为组将对其所创建的对象保留
强引用。 

组的 inactiveObject 方法可阻止从 RMI 运行时中导出与 id 关联的远程对象(
仅当没有对该对象的待定或正在执行的调用时)。使该对象将无法再接收到来的
 RMI 调用。如果该对象当前还有待定或正在执行的调用,inactiveObject 将返
回 false 且不采取任何动作。

如果 unexportObject 操作成功,意味着该对象没有待定或正在执行的调用。此
时组将通过监控器的 inactiveObject 方法通知它的 ActivationMonitor 该远程
对象当前是非活动的,以便激活器在接到下一激活请求时即重新将该远程对象激
活。如果操作成功,inactiveObject 将返回 true。如果该对象被 ActivationG
roup 认为是活动的但已被阻止导出,操作将仍有可能成功。

如果激活组不知道该对象(例如该对象先前已被报告为是非活动的,或者从未通
过该激活组来激活该对象),则 inactiveObject 方法将抛出 UnknownObjectEx
ception。如果非活动操作失败(例如,对激活器或激活组的远程调用失败),则
将抛出 RemoteException。

createGroup 方法将为当前虚拟机创建和设置激活组。只有在激活组是当前未设
定的情况下才能对它进行设置。当 Activator 为了执行到来的 activate 请求而
启动某一激活组的重新创建过程时,该激活组即通过 createGroup 方法进行设置
。组必须先向 ActivationSystem 注册一个描述符,然后才能用该方法(将注册
中得到的 ActivationID 传给它)来创建该组。

由 ActivationGroupDesc(即 desc)指定的组必须是 ActivationGroup 的具体
子类并具有公共构造函数。该公共构造函数取两个参数:一个是组的 Activatio
nGroupID;另一个是 MarshalledObject,它含有组的初始化数据(从组的Activ
ationGroupDesc 中获得的)。注意: 如果应用程序要创建自己的自定义激活组
,该组必须在构造函数中设置安全管理器。否则将不能在该组中激活对象。

创建完组后,即通知 ActivationSystem 该组已通过调用 activeGroup 方法(该
方法将返回组的 ActivationMonitor)而被激活。应用程序不必单独调用 activ
eGroup,因为 createGroup 方法将负责这一回调。

一旦组被创建,对 currentGroupID 方法的后续调用都将返回该组的标识符,直
到该组变成非活动组为止。那时,currentGroupID 方法将返回 null。

参数 incarnation 表示当前的组化身数,也就是该组被激活的次数。一旦组被成
功创建,化身数就被用作 activeGroup 方法的参数。化身数从 0 开始。如果该
组已经存在,或在组的创建过程中出错,createGroup 方法将抛出 ActivationE
xception。

setSystem 方法用于设置虚拟机的 ActivationSystem (system)。只有当前没有
组为活动组时才能对激活系统进行设置。如果没有通过显式调用 setSystem 来设
置激活系统,则 getSystem 方法将尝试通过在 Activator 的注册服务程序中查
找名称 java.rmi.activation.ActivationSystem 来获得对 ActivationSystem 
的引用。缺省情况下,查找激活系统所用的端口号将由 ActivationSystem.SYST
EM_PORT 定义。通过设置属性 java.rmi.activation.port 可将该端口覆盖掉。
如果调用 setSystem 时激活系统已经设置好,则该方法将抛出 ActivationExce
ption。

getSystem 方法返回该虚拟机的激活系统。激活系统可由 setSystem 方法(前述
)设置。

activeObject 方法是一个受保护的方法。子类将用它来对组监控器进行 active
Object 回调,以通知监控器具有指定激活 id 且其 stub 包含在 mobj 中的远程
对象现在是活动的。这一调用只是转发给组的 ActivationMonitor。

inactiveGroup 方法是一个受保护的方法。子类用它来通知组监控器该组已变成
非活动的。当组中每个参与虚拟机中激活活动的对象都变成非活动时,子类就进
行此调用。 

 

7.4.9 MarshalledObject 类 
MarshalledObject 是某个对象的容器,它允许在进行 RMI 调用时将该对象当作
一个参数来传递,但它延迟该对象在接收端上的序列化恢复,直到应用程序明确
地请求该对象(通过调用该容器对象)。包含在该 MarshalledObject 中的可序
列化对象是用相同的语义(该语义作为 RMI 调用中的参数来传递)来序列化和序
列化恢复的(请求时)。也就是说,MarshalledObject 中的任一远程对象都可表
示为其 stub 的序列化实例。MarshalledObject 所包含的对象可以是远程对象、
非远程对象或远程对象和非远程对象的完整图形。

当对象被放入 MarshalledObject 的 wrapper 中时,该对象的序列化形式将被注
释为 cadebase  URL(可从中加载类);同样,当从对象的 MarshalledObject 
的 wrapper 中取回该对象时,如果本地没有该对象的代码,则使用该 URL(序列
化时所注解的)来定位和加载该对象类的字节代码。

package java.rmi;
public final class MarshalledObject implements java.io.Serializable
{
public MarshalledObject(Object obj)
throws java.io.IOException;

public Object get()
throws java.io.IOException, ClassNotFoundException;

public int hashCode();

public boolean equals();
}


MarshalledObject 的构造函数将可序列化的对象 obj 作为单一参数,并将对象
的编组表示存放在字节流中。对象的编组表示保存了对象在 RMI 调用时所传递的
语义:

流中的每个类都被注解为其 cadebase URL,以便在重构该对象(通过调用 get 
方法)时可以找到各个类的字节代码并进行加载; 
远程对象由它们的代理服务器 stub 所代替。 
当把类 MarshalledObject 的实例写到 java.io.ObjectOutputStream 中时,所
含对象的编组形式(在构造中创建)亦被写到流中。因此,只有字节流才被序列
化。

当从 java.io.ObjectInputStream 中读取 MarshalledObject 时,并不把所包含
的对象序列化恢复为一个具体对象;该对象将一直保持其编组表示,直到该已编
组对象的 get 方法被调用为止。

get 方法总是要用所含对象的编组形式来重新构造该对象。内部表示将用解编参
数(用于 RMI 调用)所用的语义来进行序列化恢复。因此,对象表示的序列化恢
复将用嵌入对象序列化流中的 URL 注解来加载类的代码(如果本地没有该代码)


对象编组表示的 hashCode 与传递给构造函数的对象相同。如果进行比较的对象
的编组表示是等价的,则 equals 方法将返回 true。该 equals 方法所采用的比
较将忽略类的 cadebase 注解,即除了序列化表示中各个类的 cadebase 外,只
要两个对象具有相同的序列化表示,则这两个对象就是等价的。


--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.191.124]

[关闭][返回]