接口类型的映射
From OpenOffice.org Wiki
UNO 接口类型被映射成一个同名的公共 Java 接口。与表示 UNO 序列、枚举、结构和异常类型的 Java 类不同,空引用对表示 UNO 接口类型的 Java 接口实际上是合法值,即 Java 空引用表示 UNO 空引用。
如果一个 UNO 接口类型继承一个或多个其他接口类型,则 Java 接口是对应的 Java 接口的子接口。UNO 接口类型 com.sun.star.uno.XInterface 很特殊:只有当该类型用作另一个接口类型的基类型时,它才被映射成 Java 类型 com.sun.star.uno.XInterface。在其他所有情况下(用作序列类型的组件类型、结构或异常类型的成员或者接口方法的参数或返回类型时),它都被映射成 java.lang.Object。然而,该类型的有效 Java 值只是 Java 空引用和对实现 com.sun.star.uno.XInterface 的 java.lang.Object 这些实例的引用。
如下形式的 UNO 接口属性
[attribute] Type Name {
get raises (ExceptionG1, ..., ExceptionGM);
set raises (ExceptionS1, ..., ExceptionSM);
};
用两种 Java 接口方法表示
Type getName() throws ExceptionG1, ..., ExceptionGM; void setName(Type value) throws ExceptionS1, ..., ExceptionSM;
如果属性被标记为 readonly,则没有设置方法。属性是否被标记为 bound 对生成的 Java 方法的签名没有影响。
如下形式的 UNO 接口方法
Type0 name([in] Type1 arg1, [out] Type2 arg2, [inout] Type3 arg3)
raises (Exception1, ..., ExceptionN);
用 Java 接口方法表示
Type0 name(Type1 arg1, Type2[] arg2, Type3[] arg3)
throws Exception1, ..., ExceptionN;
UNO 方法是否被标记为 oneway 对生成 Java 方法的签名没有影响。可以看出,out 和 inout 参数要特殊处理。为了便于解释,以 UNOIDL 定义为例
struct FooStruct {
long nval;
string strval;
};
interface XFoo {
string funcOne([in] string value);
FooStruct funcTwo([inout] FooStruct value);
sequence<byte> funcThree([out] sequence<byte> value);
};
UNO 方法调用的语义是将任意 in 或 inout 参数的值从调用程序传递到被调用程序,如果方法没有标记为 oneway 并且执行成功终止,被调用程序将向调用程序传递回返回值和任意 out 或 inout 参数的值。因此,in 参数和返回值的处理很自然地映射成 Java 方法调用的语义。但是,UNO out 和 inout 参数则被映射成对应的 Java 类型的数组。每个这样的数组都必须至少有一个元素(即其长度至少必须为 1;实际上,其长度没有必要更大。)因此,与 UNO 接口 XFoo 对应的接口如下:
public interface XFoo extends com.sun.star.uno.XInterface {
String funcOne(String value);
FooStruct funcTwo(FooStruct[] value);
byte[] funcThree(byte[][] value);
}
下面说明如何将 FooStruct 映射到 Java:
public class FooStruct {
public int nval;
public String strval;
public FooStruct() {
strval="";
}
public FooStruct(int nval, String strval) {
this.nval = nval;
this.strval = strval;
}
}
将一个值作为 inout 参数提供时,调用程序必须将输入值写到数组的索引 0 对应的元素中。当函数返回成功时,索引 0 对应的值反映输出值,该值可以是未修改的输入值、输入值的已修改副本或一个全新的值。对象 obj 实现 XFoo:
// calling the interface in Java
obj.funcOne(null); // error, String value is null
obj.funcOne(""); // OK
FooStruct[] inoutstruct= new FooStruct[1];
obj.funcTwo(inoutstruct); // error, inoutstruct[0] is null
inoutstruct[0]= new FooStruct(); // now we initialize inoutstruct[0]
obj.funcTwo(inoutstruct); // OK
当方法接受作为 out 参数的一个自变量时,必须提供一个值,而且必须放在数组的索引 null 处。
// method implementations of interface XFoo
public String funcOne(/*in*/ String value) {
assert value != null; // otherwise, it is a bug of the caller
return null; // error; instead use: return "";
}
public FooStruct funcTwo(/*inout*/ FooStruct[] value) {
assert value != null && value.length >= 1 && value[0] != null;
value[0] = null; // error; instead use: value[0] = new FooStruct();
return null; // error; instead use: return new FooStruct();
}
public byte[] funcThree(/*out*/ byte[][] value) {
assert value != null && value.length >= 1;
value[0] = null; // error; instead use: value[0] = new byte[0];
return null; // error; instead use: return new byte[0];
}
| Content on this page is licensed under the Public Documentation License (PDL). |

