| |
Creating and calling objects
For the purposes of this introduction, it
really makes no difference what Java objects we use, so let's use a
little class called GregorianCalendar
from the standard Java libraries:
set cal [java::new java.util.GregorianCalendar]
The the
java::new command accepts the fully-qualified name of a Java
class, and produces a new object using the appropriate constructor.
Since the GregorianCalendar class is in the java.util package,
its fully-qualified name is java.util.GregorianCalendar. The
interpreter will print something like "java0x1", which is a reference
to the java object we just created.
Let's just verify that this object is what we think it is:
java::info class $cal
(Which returns java.util.GregorianCalendar.)
The java::info command performs introspection
on a Java object. For example, we can also find out the object's
superclass:
java::info superclass $cal
Other useful options include fields, which lists the public
variables of an object, and methods, which lists the
methods of an object. (See the
java::info man page.)
What's a Java package?
Java has packages too, although they are more pervasive and
structured than in Tcl. Java requires that every class be located in a
package, such as java.util (all of the JDK is located within
the java package), or tcl.lang (where the Tcl Blend and
Jacl classes are located). The directory structure reflects the
package structure, so that the class
java.util.GregorianCalendar will be located in the directory
java/util/GregorianCalendar, relative to what is know as the
classpath. (Let's avoid talking about the classpath until
later.)
(By the way, you don't use the Tcl package to load
Java packages or classes. Java will find and load the classes
automatically when it needs them.)
We can now call
methods on this object, using an object-oriented style of
syntax. Since we set the variable cal the returned object, we
can, for example, go:
$cal toString
Well, the printed result is less than helpful, but you can
at least see that there's useful information in there! (Every Java
object has a toString method, which produces a
string containing a "useful" description of the object.) Let's
try something else: first we get the time from the calendar
with the getTime method, and then we print it:
set currentTime [$cal getTime]
$currentTime toString
This will print something like "Wed Jul 29 18:16:27 PDT 1998."
(What's the class of currentTime?) By the way, the value in the
calendar is not the current system clock, just the clock at the
time we created the calendar -- if you execute the above code again in
five minutes time, it will print exactly the same thing. You can,
however, manipulate the time in the calendar like this:
$cal set 1998 8 15 14 0
set currentTime [$cal getTime]
$currentTime toString
Which will print the time this tutorial starts at the Tcl/Tk
conference -- don't forget to register :-). The arguments to this
version of the set method are the year, month, day, hours, and
minutes. (January is month zero, don't ask us why.)
You may have noticed that we have been assigning Java objects to
Tcl variables, even though the java object returns something that
looks like an identifier we can use to reference it (like "java0x2").
We don't always have to assign the result from a call to Java to a
variable -- but we do need to ensure that the Tcl interpreter always
has at least one reference to that object, so that the object won't
get garbage-collected while you still need it.
For example, this is fine:
[$cal getTime] toString
The object returned by getTime has the toString call
made on it while the interpreter still has a reference to it, so it
won't be garbage-collected until we're done with it. If however, we
were to do this:
set id [lindex [split [$cal getTime] x] 1]
java0x$id toString
then there's a good chance that you'll lose the object and get a
run-time error. Why you would want to do this is anybody's guess --
but the lesson is that Java objects need to be referenced or you'll
lose them. Tcl Blend does provide two commands that allow you to
increment and decrement an object's reference count: java::lock
and java::unlock.
Our preference is simply to treat Java objects like proper opaque
object references, and not as Tcl strings or lists.
Bogon alert!
Always assign the return result from a call to Java to a Tcl variable
if you intend to keep that object.
Summary of this section
- The command java::new creates a java object.
- The command java::info performs introspection on a Java object.
- The syntax
objectReference methodName [args]
calls methods of an object.
| |