Two forms of signatures are accepted: simple and full. A simple signature is a single element list containing the name of the method or constructor. In most cases a simple signature is all that is needed, as the Java method resolver is able to disambiguate overloaded Java methods based on the types of Java object arguments. There are some cases where the Java method resolver is unable to determine which Java method you intended to invoke, so you will need to use the full signature for the method or constructor. The full signature is used to distinguish between two or more methods or constructors that have the same number of arguments. The full signature of a method is a Tcl list containing the method name followed by the name of the Java object type for each parameter of the method.
String
object and store a reference to
it in a Tcl variable.
set jstr [java::new String "I am a Java string"]
There are a couple of things that you should note about this example.
First, the constructor signature used here is a simple signature,
that is a list containing a single element {String}
.
The system will automatically check to see if a class name that contains
no dots lives in the java.lang
package. In this
example, the class named String
does exist in the
java.lang
package, so an instance of
java.lang.String
is allocated. The second thing
to note about this example is that the Java method resolver
is invoked to disambiguate an overloaded constructor signature.
Here is a list of the java.lang.String
constructors
that take a single argument.
String(byte[])
String(char[])
String(String)
String(StringBuffer)
By default a Tcl string will be converted to a java.lang.String
,
so the method resolver picks the String(String)
constructor.
One could also invoke the constructor using a full signature.
set jstr [java::new {String String} "I am a Java string"]
In this case, the Tcl string is converted to a java.lang.String
and the String(String)
constructor is invoked. The only
difference is that the Java method resolver is not used when a full
signature is provided.
Let's examine a more complicated example, assume a method is to be invoked on the following Java class.
import java.util.*;
public class A {
public String foo(Hashtable h) {return "H";}
public String foo(Vector v) {return "V";}
}
One could use a full signature to invoke the overloaded foo
method, but it is easier to give a simple signature and let the method
resolver do the work for us.
% set hash [java::new java.util.Hashtable]
% set A [java::new A]
% $A foo $hash
H
In the example above, the type of the argument object is
known to be a java.util.Hashtable
. The
method resolver will automatically choose the correct
overloaded foo
method, ignoring the
version of foo
that accepts a Vector
.
In some cases, the method resolver is not able to choose a method to
invoke based on the type(s) of the argument(s).
If this occurs, the method resolver will give up and return an error
message indicating which methods could not be disambiguated.
% $A foo "a string"
ambiguous method signature, could not choose between {foo java.util.Hashtable} {foo java.util.Vector}
In some cases, the method resolver will not be able to automatically resolve a method signature.
import java.util.*;
public class B {
public String foo(int i, Hashtable h) {return "IH";}
public String foo(char c, Vector v) {return "CV";}
}
A full signature is required in this case. The method name, the
name of the primitive type, and the name of the class type should
be passed in a list. Note that the imported class name
% java::import java.util.Hashtable
% set hash [java::new Hashtable]
java0x1
% set b [java::new B]
java0x2
% $b foo 0 $hash
ambiguous method signature, could not choose between {foo char java.util.Vector} {foo int java.util.Hashtable}
Hashtable
is passed here, the fully qualified class name need not be passed
because the class was already imported via java::import
.
% $b {foo int Hashtable} 0 $hash
IH
Copyright © 1997-1998 Sun Microsystems, Inc.