Return-Path: <env_279751861212592262@hermes.sun.com>
Received: from pacific-carrier-annex.mit.edu by po10.mit.edu (8.9.2/4.7) id NAA17750; Fri, 10 Jan 2003 13:56:55 -0500 (EST)
Received: from hermes.sun.com (hermes.sun.com [64.124.140.169])
	by pacific-carrier-annex.mit.edu (8.9.2/8.9.2) with SMTP id NAA28663
	for <alexp@mit.edu>; Fri, 10 Jan 2003 13:53:21 -0500 (EST)
Date: 10 Jan 2003 09:09:40 -0800
From: "JDC Tech Tips" <sunmail@hermes.sun.com>
To: alexp@mit.edu
Message-Id: <279751861212592262@hermes.sun.com>
Subject: Core Java Technologies Tech Tips, Jan. 10, 2003 (Using Charsets and Encodings, Using Reflection to Create Class Instances)
Mime-Version: 1.0
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
X-Mailer: SunMail 1.0

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>
Core Java Technologies Technical Tips
</title>

<style type="text/css">

code {color: #333333; font-family: Verdana, Courier, Monospace; font-size: 10pt}
pre {color: #333333; font-family: Verdana, Courier, Monospace; font-size: 10pt}
body, div, span {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
td, th {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
tr {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
table {font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
p {color: #333333; font-family: arial,helvetica,sans-serif; font-size: 10pt}
li {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
br {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
div {color: #666699; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
sup {font-family: Arial, Helvetica, sans-serif; font-size: 5pt}
h3 {color: #666699; font-family: Arial, Helvetica, sans-serif; font-size: 11pt}
h4, b {color: #666699; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
blockquote, input, select {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
ul, ol {color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
a:link {font-size: 10pt; font-family: Arial, Helvetica, sans-serif; color:#666699 }
span.purple {font-weight: bold; color: #666699; font-family: Arial, Helvetica, sans-serif; font-size: 10pt}
span.small {font-size: 8pt; font-family: Arial, Helvetica, sans-serif; color:#333333 }
span.link {font-size: 8pt; font-family: Arial, Helvetica, sans-serif; color:#666699 }
</style>

</head>

<body bgcolor="#ffffff">
<a name="top"></a>
<table border="0" cellpadding="0" cellspacing="0" width="611">
<tr>
<td colspan="3" bgcolor="#cccccc" width="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" border="0" alt="image"></td>
</tr>

<tr>
<td bgcolor="#cccccc" width="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" border="0" alt="image"></td>

<td>
<table border="0" cellpadding="0" cellspacing="0" width="611">
<tr>
<td colspan="2"><a href="http://bulkmail2.sun.com/CTServlet?id=1042218004541" target="_blank"><img src="http://developer.java.sun.com/images/headers/core_ttips_hdr.jpg" width="611" height="160" alt="Core Java Technologies Technical Tips" border="0"></a></td>
</tr>

<tr>
<td colspan="2" bgcolor="#cccccc" width="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" border="0" alt="image"></td>
</tr>

<!-- ================== -->
<!-- Start Main Content -->
<!-- ================== -->

<tr>
<td height="20">&nbsp;&nbsp;&nbsp;<a href="http://bulkmail2.sun.com/CTServlet?id=1042218004573" target="_blank" style="text-decoration:none;" target="_blank">View this issue as simple text</a></td>
<td align="right" height="20"><span class="purple">January 10, 2003</span>&nbsp;&nbsp;&nbsp;&nbsp;</td>
</tr>

<tr><td colspan="2">

<FORM METHOD="GET" ACTION="http://search.java.sun.com/search/java/" target="_blank">
<table border="0" cellpadding="10" cellspacing="0" width="100%">
<tr>
<td>
        
<table border="0" cellpadding="3" cellspacing="0" width="100%">
<tr> 
<td align="left" VALIGN="middle" width="20%"><h3>In this Issue</h3></td>
              
<td valign="middle" align="right" width="70%">
<font size="2">
<INPUT TYPE="text" SIZE="15" MAXLENGTH="128" NAME=qt></FONT></td>
            
<td VALIGN="middle" WIDTH="55">
<INPUT TYPE="image" SRC="http://developer.java.sun.com/images/v4a_search.gif" ALT="Search" value="search" BORDER="0" WIDTH="55"></td>
</tr>
</table>

</FORM>

<p>
Welcome to the Core Java<font size="-2"><sup>TM</sup></font> Technologies Tech Tips, January 10, 2003. Here you'll get tips on using core Java technologies and APIs, such as those in Java 2 Platform, Standard Edition (J2SE<font size="-2"><sup>TM</sup></font>).
</p>

<p>
This issue covers:
</p>

<p>
<a href="#1"><img src="http://developer.java.sun.com/images/anchor.gif" border="0" alt="">Using Charsets and Encodings</a>
<br>    
<a href="#2"><img src="http://developer.java.sun.com/images/anchor.gif" border="0" alt="">Using Reflection To Create Class Instances</a>
</p>

<p>
These tips were developed using Java 2 SDK, Standard Edition, v 1.4. 
</p>

<p>
This issue of the Core Java Technologies Tech Tips is written by Glen McCluskey. 
</p>

<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">

<!-- Grey Horizontal Line Begins Here -->

<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="Pixel" border="0"></td>
</tr>
</table> 

<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">

<!-- Grey Horizontal Line Begins Here -->

<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="Pixel" border="0"></td>
</tr>
</table> 

<!-- Grey Horizontal Line ends Here -->

<a name="1"></a>

<h3>USING CHARSETS AND ENCODINGS</h3>

<p>
Suppose that you're doing some Java programming, and have need to write characters to a file:
</p>

<pre>
    import java.io.*;
    
    public class Encode1 {
        public static void main(String args[]) 
            throws IOException {
                Writer writer = new FileWriter(&quot;out&quot;);
                writer.write(&quot;testing&quot;);
                writer.close();
        }
    }
</pre>

<p>
When you run this program in the United States in the Solaris<font size="-2"><sup>TM</sup></font> Operating Environment or on the Windows platform, the result is a text file "out" of 7 bytes. This is what you would expect.
</p>

<p>
But there is an important issue here. Java characters are 16-bit, that is, each character is two bytes long. The Encode1 program writes a 7-character string to a file, and the result is a 7-byte file. You might ask: what happened to the other bytes, shouldn't there be 14 bytes written?
</p>

<p>
This issue falls under the title &quot;character encodings&quot;. The problem is how to map between 16-bit characters representing Java data, and 8-bit bytes stored in data files. And in fact, it's trickier than simply &quot;widening&quot; or &quot;narrowing&quot; the character between 8 and 16 bits because there are literally hundreds of different character encoding schemes in use around the world. This means that the specific sequence of 8-bit bytes needed to represent a particular Java string changes from platform to platform and from locale to locale.
</p>

<p>
The Java system solves this problem by allowing you to choose the particular encoding scheme that's required when writing out characters. It also provides a reasonable default encoding based on your platform and locale. The Java system supports default encodings for performing I/O, as in the example above. In addition, you can also specify other named encodings (&quot;charsets&quot;). These encodings are described by string names, such as &quot;UTF-8&quot;, and by instances of the <code>java.nio.charset.Charset</code> class. <code>Charset</code> is abstract, so the actual instances are objects of subclasses of <code>Charset</code>.
</p>

<p>
In the Encode1 example, one way of solving the encoding problem is to always write two bytes out for each character. However the file will have null bytes interspersed. Another approach is to throw away the high byte of each Java character. This will work in the example above, but it wouldn't work if you tried to write a string of Greek or Japanese instead..
</p>

<p>
What actually happens in this example is that the second approach is used -- the high byte is discarded. If you change the output line in the Encode1 program from:
</p>

<pre>
    writer.write(&quot;testing&quot;);
</pre>

<p>
to:
</p>

<pre>
    writer.write(&quot;testing\u1234&quot;);
</pre>

<p>
the total output length will be 8 bytes instead of 7, even though the Unicode character \u1234 cannot be represented using a single byte. 
</p>

<p>
"&quot;Discard&quot; in the previous discussion can have a couple of meanings. If the high byte of a Java character is 0, as is the case for characters representing 7-bit ASCII, then discard means to omit the high byte. However, another meaning applies to the situation where you have a Java character that is not mappable using a particular encoding. In such a case the character (two bytes) may be replaced by a default substitution byte. In the case above, \u1234 is replaced with 0x3f.
</p>

<p>
Let's now look at how to use charsets, mappings between characters and bytes. One basic question you might have is: what charsets are available? Here's a program that displays a list:
</p>

<pre>
    import java.nio.charset.*;
    import java.util.*;
    
    public class Encode2 {
        public static void main(String args[]) {
            Map availcs = Charset.availableCharsets();
            Set keys = availcs.keySet();
            for (Iterator iter = 
                keys.iterator();iter.hasNext();) {
                    System.out.println(iter.next());
                }
        }
    }
</pre>

<p>
The output should look something like this (but without the &quot;*&quot; character):
</p>

<pre>
    ISO-8859-1*
    ISO-8859-15
    US-ASCII*
    UTF-16*
    UTF-16BE*
    UTF-16LE*
    UTF-8*
    windows-1252
</pre>

<p>
The &quot;*&quot; is shown here to identify charsets that must be supported on all Java platforms.
</p>

<p>
Another basic question: what is the default charset on my local system? Here's a program that displays the name of the default:
</p>

<pre>
    import java.io.*;
    import java.nio.charset.*;
    
    public class Encode3 {
        public static void main(String args[]) 
            throws IOException {
                FileWriter filewriter = 
                    new FileWriter("out");
                String encname = 
                    filewriter.getEncoding();
                filewriter.close();
                System.out.println(
                    "default charset is: &quot; + encname);
    
                /*
                Charset charset1 = 
                    Charset.forName(encname);
                Charset charset2 = 
                    Charset.forName(&quot;windows-1252&quot;);
                if (charset1.equals(charset2)) {
                    System.out.println(
                        &quot;Cp1252/windows-1252 equal&quot;);
                }
                else {
                    System.out.println(
                        &quot;Cp1252/windows-1252 unequal&quot;);
            }
            */
        }
    }
</pre>

<p>
When you run this program, you might see a result like this:
</p>

<pre>
    default charset is: Cp1252
</pre>

<p>
Notice that this charset is not on the list of required charsets that every Java implementation must support. There is no requirement that the default charset must be one of the required charsets. This example also has some commented-out logic that shows how you can determine whether two charsets are equal or not. It turns out that &quot;windows-1252&quot; and &quot;Cp1252&quot; are in fact names for a single charset. The logic is commented out because there is no requirement that the Cp1252 charset be supported, and so the logic here might not be meaningful to you.
</p>

<p>
You may have seen other ways to get the default local charset name, such as querying the &quot;file.encoding&quot; system property. This approach might work, but this property is not guaranteed to be defined on all Java platforms.
</p>

<p>
In the Encode3 program, <code>Charset.forName</code> is used to find the Charset object for a string name such as &quot;US-ASCII&quot;. Here's another example that uses this technique:
</p>

<pre>
    import java.nio.charset.*;
    
    public class Encode4 {
        public static void main(String args[]) {
            if (args.length != 1) {
                System.out.println(
                    &quot;missing charset name&quot;);
                System.exit(1);
            }
    
            String charsetname = args[0];
            Charset charset;
    
            try {
                charset = Charset.forName(charsetname);
                System.out.println(
                    &quot;charset lookup successful&quot;);
            }
            catch (UnsupportedCharsetException exc) {
                System.out.println(
                    &quot;unknown charset: &quot; + charsetname);
            }
        }
    }
</pre>

<p>
If you run the program, like this:
</p>

<pre>
    $ java Encode4 XYZ
</pre>

<p>
it will check whether &quot;XYZ&quot; is a supported Charset on the local system, and if so, obtain the Charset object.
</p>

<p>
Given all this background, how do you actually make use of charsets? Here's a rework of the first example, Encode1:
</p>

<pre>
    import java.io.*;
    
    public class Encode5 {
        public static void main(String args[]) 
            throws IOException {
                FileOutputStream fileoutstream =
                    new FileOutputStream(&quot;out&quot;);
                Writer writer = new OutputStreamWriter(
                    fileoutstream, &quot;UTF-8&quot;);
                writer.write(&quot;testing&quot;);
                writer.close();
        }
    }
</pre>

<p>
The Encode1 program is not portable. It applies the default charset, which can vary based on platform and locale. By contrast, the Encode5 program uses a standard charset (UTF-8). As mentioned earlier, the default encoding used in the Encode1 example discards the high byte of Java characters. Using the UTF-8 encoding solves this problem. If you change the output line in the Encode program from:
</p>

<pre>
    writer.write(&quot;testing&quot;);

to:

    writer.write(&quot;testing\u1234&quot;);
</pre>

<p>
it still works. And UTF-8 has the advantage of handling 7-bit ASCII in a graceful way.
</p>

<p>
Here's another example. It shows how you can convert Java strings to byte vectors, specifying an encoding:
</p>

<pre>
    import java.io.*;
    
    public class Encode6 {
        public static void main(String args[])
        throws UnsupportedEncodingException {
            String str = "testing";
    
            byte bytevec1[] = str.getBytes();
            byte bytevec2[] = str.getBytes(&quot;UTF-16&quot;);
    
            System.out.println(&quot;bytevec1 length = &quot; +
                bytevec1.length);
            System.out.println(&quot;bytevec2 length = &quot; +
                bytevec2.length);
        }
    }
</pre>

<p>
The output on your system should look something like this:
</p>

<pre>
    bytevec1 length = 7
    bytevec2 length = 16
</pre>

<p>
The first conversion applies the default charset. The second conversion uses the UTF-16 charset. 
</p>

<p>
There's one final thing to discuss about character encodings. You might wonder what a typical mapping or encoding algorithm really looks like. Here is some actual code taken from <code>DataOutputStream.writeUTF</code>. It's used to map a character vector into a byte vector:
</p>

<pre>
    for (int i = 0; i &lt; strlen; i++) {
        c = charr[i];
        if ((c &gt;= 0x0001) && (c &lt;= 0x007F)) {
            bytearr[count++] = (byte) c;
        }
        else if (c &gt; 0x07FF) {
            bytearr[count++] = 
                (byte) (0xE0 | ((c &gt;&gt; 12) & 0x0F));
            bytearr[count++] = 
                (byte) (0x80 | ((c &gt;&gt;  6) & 0x3F));
            bytearr[count++] = 
                (byte) (0x80 | ((c &gt;&gt;  0) & 0x3F));
        }
        else {
            bytearr[count++] = 
                (byte) (0xC0 | ((c &gt;&gt;  6) & 0x1F));
            bytearr[count++] = 
                (byte) (0x80 | ((c &gt;&gt;  0) & 0x3F));
        }
    }
</pre>

<p>
Characters are taken from charr, converted into 1-3 bytes, and written into bytearr. Characters in the range 0x1 - 0x7f (7-bit ASCII) are mapped into themselves. Characters with value 0x0 and in the range 0x80 - 0x7ff are mapped into two bytes. All other characters are mapped into three bytes.
</p>

<p>
For more information about charsets and encodings, see section 9.7.1, Character Encodings, in &quot;<a href="http://bulkmail2.sun.com/CTServlet?id=1042218004355" target="_blank">The Java<font size="-2"><sup>TM</sup></font> Programming Language Third Edition</a>&quot; by Arnold, Gosling, and Holmes. Also see the <a href="http://bulkmail2.sun.com/CTServlet?id=1042218004376" target="_blank">documentation for Supported Encodings</a> and <a href="http://bulkmail2.sun.com/CTServlet?id=1042218004391" target="_blank">Charset</a>. The document Unicode Transformation Formats: <a href="http://bulkmail2.sun.com/CTServlet?id=1042218004423" target="_blank">UTF-8 &amp; Co.</a> is another good place to learn about charsets and encodings.
</p>

<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">
<tr>
<td>
<div align="right">
<a href="#top">back to top<img src="http://developer.java.sun.com/images/back_to_top.gif" border="0" alt="image"></a>
</div>
</td></tr>

<tr><td bgcolor="#ffffff" height="2"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="Pixel" border="0"></td></tr>

<!-- Grey Horizontal Line Begins Here -->

<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="Pixel" border="0"></td>
</tr>
</table> 

<!-- Grey Horizontal Line ends Here -->

<a name="2"></a>

<h3>USING REFLECTION TO CREATE CLASS INSTANCES</h3>

<p>
Imagine that you're doing some Java programming, and you need to create a new instance of the A class. You write some code like this:
</p>

<pre>
    A aref = new A();
</pre>

<p>
Pretty obvious, right?
</p>

<p>
Suppose, however, you take a step further and specify that the name of the class is found in a string made available at run time. It's still possible to proceed, like this:
</p>

<pre>
    String classname; // can be either A, B, or C

    A aref = null;
    B bref = null;
    C cref = null;

    if (classname.equals(&quot;A&quot;))
        aref = new A();
    else if (classname.equals(&quot;B&quot;))
        bref = new B();
    else
        cref = new C();
</pre>

<p>
This code works, but it's cumbersome. Also, it can't be expanded much further without major effort.
</p>

<p>
There's another approach that works much better in this kind of situation. The basic idea is that you use <code>Class.forName</code> to obtain a <code>java.lang.Class</code> object for a class whose string name you specify. <code>java.lang.Class</code> is a class whose instances represent Java types, such as classes and interfaces and arrays. After you obtain a <code>java.lang.Class</code> instance, you can call <code>newInstance</code> to create a new object of the class represented by the <code>java.lang.Class</code> instance. The code looks like this:
</p>

<pre>
    Class cls = Class.forName(classname);

    Object obj = cls.newInstance();
</pre>

<p>
This sequence creates an object of the class whose string name is <code>classname</code>.
</p>

<p>
After you have a <code>java.lang.Class instance</code>, you can also find out other things about the represented class, for example, what methods and fields it contains. You can look up methods by name, and use reflection to call these methods.
</p>

<p>
Let's look at an example to make these ideas a little more concrete. The example uses <code>java.lang.Class</code> and reflection to implement a class and method exerciser. The idea is that you have some classes and methods, and you'd like to write a driver program to test them. For example, for this input:
</p>

<pre>
    $ java NewDemo A string1 string2 @ f2 string3 string4 string5
</pre>

<p>
the driver creates an object of class A, using string1/string2 as string arguments to the A constructor. The driver then calls A.f2 for the created object, using string3/string4/string5 as arguments to the f2 method.
</p>

<p>
Note that the driver program doesn't know anything about the A class. It's written in a general way to work with any class. The driver looks up and manipulates class and method names using <code>java.lang.Class</code> and reflection.
</p>

<p>
Here's what the code looks like:
</p>

<pre>
    import java.lang.reflect.*;
    
    public class NewDemo {
        Class cls;
    
        Object obj;
    
        Constructor ctor;
        Object ctorargs[];
    
        Method meth;
        Object methargs[];
    
        String args[];
        int divpos;
    
        // parse input of the form:
        //
        //  classname arg1 arg2 ... 
        //   @ methodname arg1 arg2 ...
    
        public NewDemo(String a[]) throws 
            ClassNotFoundException, 
            NoSuchMethodException {
    
            args = a;
    
            // search for @ divider in input
    
            divpos = -1;
            for (int i = 0; i &lt; args.length; i++) {
                if (args[i].equals(&quot;@&quot;)) {
                    divpos = i;
                    break;
                }
            }
            if (divpos &lt; 1 || divpos + 1 == args.length) {
                throw new IllegalArgumentException(
                    &quot;bad syntax&quot;);
            }
    
            // load appropriate class 
            // and get Class object
    
            String classname = args[0];
            cls = Class.forName(classname);
    
            // find the constructor, 
            // if arguments specified for it
    
            if (divpos &gt; 1) {
                Class ptypes[] = new Class[divpos - 1];
                for (int i = 0; i &lt; ptypes.length; i++) {
                    ptypes[i] = String.class;
                }
                ctor = cls.getConstructor(ptypes);
    
                // set up the constructor arguments
    
                ctorargs = new Object[divpos - 1];
                for (int i = 0; i &lt; ctorargs.length; i++) {
                    ctorargs[i] = args[i+1];
                }
            }
    
            // find the right method
    
            String methodname = args[divpos + 1];
            int firstarg = divpos + 2;
            Class ptypes[] = 
                new Class[args.length - firstarg];
            for (int i = 0; i &lt; ptypes.length; i++) {
                ptypes[i] = String.class;
            }
            meth = cls.getMethod(methodname, ptypes);
    
            // set up the method arguments
    
            methargs = new Object[ptypes.length];
            for (int i = 0; i &lt; methargs.length; i++) {
                methargs[i] = args[firstarg + i];
            }
        }
    
        // create an object of the specified class
    
        public void createObject() throws 
            InstantiationException,
            IllegalAccessException, 
            InvocationTargetException {
        
            // if class has no-arg constructor, 
            // use it
    
            if (ctor == null) {
                obj = cls.newInstance();
            }
    
            // otherwise use constructor with arguments
    
            else {
                obj = ctor.newInstance(ctorargs);
            }
        }
    
        // call the method and display its return value
    
        public void callMethod() throws 
            IllegalAccessException,
            InvocationTargetException {
    
            Object ret = meth.invoke(obj, methargs);
            System.out.println(&quot;return value: &quot; + ret);
        }
    
        public static void main(String args[]) {
    
            // create a NewDemo instance 
            // and call the method
    
            try {
                NewDemo nd;
    
                nd = new NewDemo(args);
                nd.createObject();
                nd.callMethod();
            }
    
            // display any resulting exception
    
            catch (Exception e) {
                System.out.println(e);
                System.exit(1);
            }
        }
    }
</pre>

<p>
Here is a test class you can use with the demo:
</p>

<pre>
    public class A {
        public A() {
            System.out.println(&quot;call: A.A()&quot;);
        }
        public A(String s1, String s2) {
            System.out.println(
                &quot;call: A.A(&quot; + s1 + &quot;,&quot; + s2 + &quot;)&quot;);
        }
        public void f1() {
            System.out.println(&quot;call: A.f1()&quot;);
        }
        public double f2(
            String s1, String s2, String s3) {
            System.out.println(&quot;call: A.f2(&quot; + s1 + &quot;,&quot; + s2 +
                    &quot;,&quot; + s3 + &quot;)&quot;);
            return 12.34;
        }
    }
</pre>

<p>
You need to compile this class in the usual way.
</p>

<p>
The <code>NewDemo</code> constructor is used to parse the input line, to find the <code>java.lang.Class</code> object for the specified class, and to find the appropriate constructor and method. Then <code>createObject</code> is called to create an instance of the class. Finally, <code>callMethod</code> is used to actually call the method for the class instance.
</p>

<p>
The constructor and method are found by creating a <code>java.lang.Class</code> vector that contains the types of each parameter to the constructor or method. This example takes the liberty of assuming that all parameters are of String type, and thus the corresponding <code>java.lang.Class</code> object is &quot;String.class&quot;. Then <code>getConstructor</code> and <code>getMethod</code> are used to find the actual constructor or method to use.
</p>

<p>
If you run the driver, by saying:
</p>

<pre>
    java NewDemo A @ f1
</pre>

<p>
The output is:
</p>

<pre>
    call: A.A()
    call: A.f1()
    return value: null
</pre>

<p>
Here are additional driver runs:     
</p>

<pre>
    java NewDemo A @ f2 str1 str2 str3 

    java NewDemo A str4 str5 @ f1

    java NewDemo A str6 str7 @ f2 str8 str9 str10
</pre>

<p>
And here are their respective results:   
</p>

<pre>
    call: A.A()
    call: A.f2(str1,str2,str3)
    return value: 12.34

    call: A.A(str4,str5)
    call: A.f1()
    return value: null

    call: A.A(str6,str7)
    call: A.f2(str8,str9,str10)
    return value: 12.34
</pre>

<p>
Some examples of driver runs with bad input are:
</p>

<pre>
    java NewDemo
    java NewDemo A
    java NewDemo A @
    java NewDemo A str1 @ f1
    java NewDemo A @ f1 str1
    java NewDemo B @ f1
    java NewDemo A str11 str12 @
    java NewDemo A @ f3 str1
</pre>

<p>
The results are:
</p>

<pre>
    java.lang.IllegalArgumentException: bad syntax
    java.lang.IllegalArgumentException: bad syntax
    java.lang.IllegalArgumentException: bad syntax
    java.lang.NoSuchMethodException
    java.lang.NoSuchMethodException: f1
    java.lang.ClassNotFoundException: B
    java.lang.IllegalArgumentException: bad syntax
    java.lang.NoSuchMethodException: f3
</pre>

<p>
The techniques illustrated here are extremely powerful, and allow you to manipulate types and methods by name at run time. These techniques are used by tools such as interpreters, debuggers, and object exercisers.
</p>

<p>
For more information about using reflection to create class instances  see section 11.2.1, The Class class, and section 11.2.6, The Method Class, in &quot;<a href="http://bulkmail2.sun.com/CTServlet?id=1042218004355" target="_blank">The Java<font size="-2"><sup>TM</sup></font> Programming Language Third Edition</a>&quot; by Arnold, Gosling, and Holmes. 
</p>

<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">

<tr>
<td>
<div align="right">
<a href="#top">back to top<img src="http://developer.java.sun.com/images/back_to_top.gif" border="0" alt="image"></a>
</div>
</td></tr>

<tr><td bgcolor="#ffffff" height="2"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="Pixel" border="0"></td></tr>

<!-- Grey Horizontal Line Begins Here -->

<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="Pixel" border="0"></td>
</tr>
</table> 

<!-- Grey Horizontal Line ends Here -->


<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td bgcolor="#ffffff" height="2"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="Pixel" border="0"></td></tr>

<h3>Reader Feedback</h3> 
<FORM METHOD="POST" ACTION="http://developer.java.sun.com/servlet/jdc.survey.TabulationServlet">
<INPUT TYPE="hidden" NAME="survey_id" VALUE="2600">
<INPUT TYPE="hidden" NAME="anonymous" VALUE="True">
<INPUT TYPE="hidden" NAME="answer_count" VALUE="3">
<INPUT TYPE="hidden" NAME="answer1" VALUE="JanCore_tt0110"> 
<INPUT NAME="answer2" TYPE="RADIO" VALUE="2">&nbsp; Very worth reading&nbsp; 
<INPUT NAME="answer2" TYPE="RADIO" VALUE="1">&nbsp; Worth reading&nbsp; 
<INPUT NAME="answer2" TYPE="RADIO" VALUE="0">&nbsp; Not worth reading&nbsp; 
 
<p>
If you have other comments or ideas for future technical tips, please type them  here: 
</p>
 
<p>
<TEXTAREA NAME="answer3" ROWS="6" COLS="50"></TEXTAREA> 
</p>
 
<p>
<INPUT TYPE="SUBMIT" VALUE="Submit"> &nbsp; <INPUT TYPE="RESET"> 
</p>

<p> 
Have a question about Java<font size="-2"><sup>TM</sup></font> programming? Use  
<a href="http://bulkmail2.sun.com/CTServlet?id=1042218004588">Java Online Support.</a> 
</p>

</td></tr></table>
</FORM> 

<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">
<tr>
<td>
<div align="right">
<a href="#top">back to top<img src="http://developer.java.sun.com/images/back_to_top.gif" border="0" alt="image"></a>
</div>
</td></tr>

<tr><td bgcolor="#ffffff" height="2"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="Pixel" border="0"></td></tr>

<!-- Grey Horizontal Line Begins Here -->

<tr>
<td bgcolor="#cccccc" height="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" ALT="Pixel" border="0"></td>
</tr>
</table> 

<!-- Grey Horizontal Line ends Here -->

<br>

<span class="small">IMPORTANT: Please read our Terms of Use, Privacy, and Licensing 
policies:<br>
<a href="http://bulkmail2.sun.com/CTServlet?id=1042218004441" target="_blank"><span class="link">http://www.sun.com/share/text/termsofuse.html</span></a><br>
<a href="http://bulkmail2.sun.com/CTServlet?id=1042218004458" target="_blank"><span class="link">http://www.sun.com/privacy/</span></a><br> 
<a href="http://bulkmail2.sun.com/CTServlet?id=1042218004472" target="_blank"><span class="link">http://developer.java.sun.com/berkeley_license.html</span></a>
</span><br><br>


<span class="small">
Comments? Send your feedback on the Core Java<sup>TM</sup> Technologies Tech Tips to: <a href="mailto:jdc-webmaster@sun.com"><span class="link">jdc-webmaster@sun.com</span></a>
</span><br><br>

<span class="small">
Subscribe to other Java developer Tech Tips:
</span><br><br>

<span class="small">
- Enterprise Java Technologies Tech Tips. Get tips on using enterprise Java technologies and APIs, such as those in the Java 2 Platform, Enterprise Edition (J2EE<sup>TM</sup>).<br>
- Wireless Developer Tech Tips. Get tips on using wireless Java technologies and APIs, such as those in the Java 2 Platform, Micro Edition (J2ME<sup>TM</sup>).<br><br>
</span>
   
<span class="small">
To subscribe to these and other JDC publications:<br>
- Go to the JDC Newsletters and Publications page, choose the newsletters you want to <a href="http://bulkmail2.sun.com/CTServlet?id=1042218004487" target="_blank"><span class="link">subscribe</span></a> to and click &quot;Update&quot;.<br>
  - To unsubscribe, go to the <a href="http://bulkmail2.sun.com/CTServlet?id=1042218004487" target="_blank"><span class="link">subscriptions page</span></a>, uncheck the appropriate checkbox, and click &quot;Update&quot;.
</span><br><br>

<span class="small">ARCHIVES: You'll find the Core Java Technologies Tech Tips archives at:<br>
<a href="http://bulkmail2.sun.com/CTServlet?id=1042218004603" target="_blank"><span class="link">http://java.sun.com/jdc/TechTips/index.html</span></a>
</span><br><br>

<span class="small">Copyright 2003 <a href="http://bulkmail2.sun.com/CTServlet?id=1042218004827" target="_blank"><span class="link">Sun Microsystems, Inc.</span></a> All rights reserved.
<br>901 San Antonio Road, Palo Alto, California 94303 USA.
</span><br><br>

<span class="small">This document is protected by copyright. For more information, see:
<br><a href="http://bulkmail2.sun.com/CTServlet?id=1042218004525" target="_blank"><span class="link">http://java.sun.com/jdc/copyright.html</span></a>
</span><br><br>

<span class="small">Sun, Sun Microsystems, Java, Java Developer Connection, J2SE, J2EE, and J2ME are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.</span><br><br>


<!-- ================ -->
<!-- End Main Content -->
<!-- ================ -->

<center>
<a href="http://bulkmail2.sun.com/CTServlet?id=1042218004827" target="_blank"><img src="http://developer.java.sun.com/images/lgsun.gif" border="0" alt="Sun Microsystems, Inc."></a>
</center>

</td>
</tr>
</table>

</td></tr>
</table>
</td>

<td bgcolor="#cccccc" width="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" border="0" alt=""></td>
</tr>
<tr>
<td colspan="3" bgcolor="#cccccc" width="1"><img src="http://developer.java.sun.com/images/pixel.gif" width="1" height="1" border="0" alt=""></td>
</tr>
</table>

<table bgcolor = "#efefef"><tr><td><a href="http://bulkmail.sun.com/unsubscribe?279751861212592262">Please unsubscribe me from this newsletter.</a><img src="http://bulkmail2.sun.com/OTServlet?id=279751861212592262" width=1 height=1></td></tr></table></body>
</html>

