Having worked your way through the previous dense section, you may hope that we are done with the topic of data conversion. Unfortunately, there is more to be discussed on the topic of how JavaScript converts JavaObject objects to various JavaScript primitive types. Notice in Figure 22-3 that quite a few Java data types, including Java strings (instances of java.lang.String), are converted to JavaObject objects in JavaScript rather than being converted to actual JavaScript primitive types, such as strings. This means that when you use LiveConnect, you'll often be working with JavaObject objects.
Refer back to Table 11-1, which shows how various JavaScript data types are converted when used in various contexts. For example, when a number is used in a string context, it is converted to a string, and when an object is used in a boolean context, it is converted to the value false if it is null and true otherwise. These conversion rules don't apply to JavaObject objects, which are converted using their own rules, as follows:
When a JavaObject is used in a numeric context, it is converted to a number by invoking the doubleValue( ) method of the Java object it represents. If the Java object does not define this method, a JavaScript error occurs.
When a JavaObject is used in a boolean context, it is converted to a boolean value by invoking the booleanValue( ) method of the Java object it represents. If the Java object does not define this method, a JavaScript error occurs.
When a JavaObject is used in a string context, it is converted to a string value by invoking the toString( ) method of the Java object it represents. All Java objects define or inherit this method, so this conversion always succeeds.
When a JavaObject is used in an object context, no conversion is necessary, since it is already a JavaScript object.
Because of these different conversion rules, and for other reasons as well, JavaObject objects behave differently than other JavaScript objects, and there are some common pitfalls that you need to recognize. First, it is not uncommon to work with a JavaObject that represents an instance of java.lang.Double or some other numeric object. In many ways, such a JavaObject behaves like a primitive number value, but be careful when using the + operator. When you use a JavaObject (or any JavaScript object) with +, you are specifying a string context, so the object is converted to a string for string concatenation instead of being converted to a number for addition.
When you want to explicitly convert a JavaScript object to a primitive value, you usually call its valueOf( ) method. Note that this does not work with JavaObject objects. As we discussed earlier, the JavaObject class defines no properties of its own; all of its properties represent fields and methods of the Java object it represents. This means that JavaObject objects don't support common JavaScript methods, such as valueOf( ). In the case of our JavaObject-wrapped java.lang.Double object, you should call the Java doubleValue( ) method when you need to force the object into a primitive value.
Another difference between JavaObject objects and other JavaScript data types is that JavaObjects can be used in a boolean context only if they define a booleanValue( ) method. Suppose button is a JavaScript variable that may contain null or may hold a JavaObject that represents an instance of the java.awt.Button class. If you want to check whether the variable contains null, you might write code like this, out of habit:
if (!button) { ... }
If button is null, this works fine. But if button actually contains a JavaObject representing a java.awt.Button instance, LiveConnect tries to invoke the booleanValue( ) method. When it discovers that the java.awt.Button class doesn't define one, it causes a JavaScript error. The workaround in this case is to be explicit about what you are testing for, to avoid using the JavaObject in a boolean context:
if (button != null) { ... }
This is a good habit to get into, in any case, since it makes your code easier to read and understand.
Copyright © 2003 O'Reilly & Associates. All rights reserved.