Type Mappings
Mapping of Simple Types
The following table shows the mapping of simple UNO types to the corresponding Java types.
UNO | Java |
---|---|
void | void |
boolean | boolean |
byte | byte |
short | short |
unsigned short | short |
long | int |
unsigned long | int |
hyper | long |
unsigned hyper | long |
float | float |
double | double |
char | char |
string | java.lang.String |
type | com.sun.star.uno.Type |
any | java.lang.Object/com.sun.star.uno.Any |
The mapping between the values of the corresponding UNO and Java types is obvious, except for a few cases that are explained in the following sections:
Mapping of Unsigned Integer Types
An unsigned UNO integer type encompasses the range from 0 to 2N − 1, inclusive, while the corresponding signed Java integer type encompasses the range from −2N − 1 to 2N − 1 − 1, inclusive (where N is 16, 32, or 64 for unsigned short, unsigned long, or unsigned hyper, respectively). The mapping is done modulo N, that is: 0 is mapped to 0; 2N − 1 − 1 is mapped to 2N − 1 − 1; 2N − 1 is mapped to −2N − 1; and 2N − 1 is mapped to −1.
Users should be careful when using any of the deprecated UNO unsigned integer types. A user is responsible for correctly interpreting values of signed Java integer types as unsigned integer values in such cases.
Mapping of String
The mapping between the UNO string type and java.lang.String is straightforward, except for three details:
- Only non-null references to
java.lang.String
are allowed in the context of UNO. - The length of a string that can be represented by a
java.lang.String
object is limited. It is an error to use a longer UNO string value in the context of the Java language binding. - An object of type
java.lang.String
can represent an arbitrary sequence of UTF-16 code units, whereas a value of the UNO string type is an arbitrary sequence of Unicode scalar values. This only matters in so far as some individual UTF-16 code units (namely the individual high- and low-surrogate code points in the range D800–DFFF) have no corresponding Unicode scalar values, and are thus forbidden in the context of UNO. For example, the Java string "\uD800
" is illegal in this context, while the string "\uD800\uDC00
" would be legal. See www.unicode.org for more information on the details of Unicode.
Mapping of Type
The Java class com.sun.star.uno.Type
is used to represent the UNO type type; only non-null references to com.sun.star.uno.Type
are valid. (It is a historic mistake that com.sun.star.Type
is not final. You should never derive from it in your code.)
In many places in the Java UNO runtime, there are convenience functions that take values of type java.lang.Class
where conceptually a value of com.sun.star.uno.Type
would be expected. For example, there are two overloaded versions of the method com.sun.star.uno.UnoRuntime.queryInterface
, one with a parameter of type com.sun.star.uno.Type
and one with a parameter of type java.lang.Class
. See the documentation of com.sun.star.uno.Type
for the details of how values of java.lang.Class
are interpreted in such a context.
Mapping of Any
There is a dedicated com.sun.star.uno.Any
type, but it is not always used. An any in the API reference is represented by a java.lang.Object
in Java UNO. An Object reference can be used to refer to all possible Java objects. This does not work with primitive types, but if you need to use them as an any, there are Java wrapper classes available that allow primitive types to be used as objects. Also, a Java Object always brings along its type information by means of an instance of java.lang.Class
. Therefore a variable declared as:
Object ref;
can be used with all objects and its type information is available by calling:
ref.getClass();
Those qualities of Object
are sufficient to replace the Any
in most cases. Even Java interfaces generated from IDL interfaces do not contain Any
s, instead Object
references are used in place of Any
s. Cases where an explicit Any
is needed to not loose information contain unsigned integer types, all interface types except the basic XInterface
, and the void type.
However, implementations of those interfaces must be able to deal with real Anys that can also be passed by means of Object references. |
To facilitate the handling of the Any type, use the com.sun.star.uno.AnyConverter
class. It is documented in the Java UNO reference. The following list sums up its methods:
static boolean isArray(java.lang.Object object)
static boolean isBoolean(java.lang.Object object)
static boolean isByte(java.lang.Object object)
static boolean isChar(java.lang.Object object)
static boolean isDouble(java.lang.Object object)
static boolean isFloat(java.lang.Object object)
static boolean isInt(java.lang.Object object)
static boolean isLong(java.lang.Object object)
static boolean isObject(java.lang.Object object)
static boolean isShort(java.lang.Object object)
static boolean isString(java.lang.Object object)
static boolean isType(java.lang.Object object)
static boolean isVoid(java.lang.Object object)
static java.lang.Object toArray(java.lang.Object object)
static boolean toBoolean(java.lang.Object object)
static byte toByte(java.lang.Object object)
static char toChar(java.lang.Object object)
static double toDouble(java.lang.Object object)
static float toFloat(java.lang.Object object)
static int toInt(java.lang.Object object)
static long toLong(java.lang.Object object)
static java.lang.Object toObject(Type type, java.lang.Object object)
static short toShort(java.lang.Object object)
static java.lang.String toString(java.lang.Object object)
static Type toType(java.lang.Object object)
The Java com.sun.star.uno.Any
is needed in situations when the type needs to be specified explicitly. Assume there is a C++ component with an interface function which is declared in UNOIDL as:
//UNOIDL
void foo(any arg);
The corresponding C++ implementation could be:
void foo(const Any& arg)
{
const Type& t = any.getValueType();
if (t == cppu::UnoType< XReference >::get())
{
Reference<XReference> myref = *reinterpret_cast<const Reference<XReference>*>(arg.getValue());
...
}
}
In the example, the any is checked if it contains the expected interface. If it does, it is assigned accordingly. If the any contained a different interface, a query would be performed for the expected interface. If the function is called from Java, then an interface has to be supplied that is an object. That object could implement several interfaces and the bridge would use the basic XInterface
. If this is not the interface that is expected, then the C++ implementation has to call queryInterface
to obtain the desired interface. In a remote scenario, those queryInterface()
calls could lead to a noticeable performance loss. If you use a Java Any as a parameter for foo()
, the intended interface is sent across the bridge.
It is a historic mistake that com.sun.star.uno.Any
is not final. You should never derive from it in your code.
Content on this page is licensed under the Public Documentation License (PDL). |