Java Signatures


About:

A signature is a list that indicates a class constructor, an instance method, or a static method.

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.

Examples:

This command will create a Java 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";}
}

% 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}
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 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.