JAVA PROGRAMMING LAB LAB MANUAL

CENTRE FOR DISTANCE EDUCATION ANNA UNIVERSITY CHENNAI

ABOUT THIS LAB MANUAL
INTRODUCTION This lab manual for Java Programming is prepared for M.C.A Degree offered by Centre for Distance Education, Anna University, Chennai. There are six chapters in this manual covering how to write java programs for simple java applications and also for the features like string handling, interface, exception handling, threading, java data base connectivity etc. SETTING UP YOUR HOME COMPUTER You do not need to own a computer to take this lab, but since many of you do have one and will want to have one at home, we tell you where and how to go about setting up a Java programming environment in your computer. This lab needs the Java SDK and a text editor named TextPad. If you install these two pieces of software on your computer you will have a Java programming environment that is recommended for use in the course. Two pieces of software can also be downloaded off the internet. The next two sections tell you how to do this. DOWNLOADING THE JAVA SDK FOR YOUR COMPUTER Java was developed at Sun Microsystems Inc and there is a big web site devoted to Java. It contains news, tutorials, and the software needed to develop and run Java program: http://java.sun.com/ If you want to set up your computer with the software needed to compile and run Java programs go the java.sun.com site and click on the J2SE 1.5 SDK link in the Popular
Downloads box on the right of the screen. Don't worry if the numbers are different. That just

means it is a newer version.

2

Question: What do all those letters mean? Answer: Java 2 Standard Edition (version) 1.5 Software Development Kit. From here on we just call it the Java 2 SDK or simply the SDK. The SDK consists of a compiler, virtual machine, applet viewer, a large library of useful predefined classes, and a few other tools. Back to downloading the SDK. You should be at the following web site: http://java.sun.com/j2se/1.5.0/download.jsp Now look at the heading, Download J2SE v 1.4.1_03 (the numbers may be different), find the version appropriate for you (probably: Windows (all languages, including
English)) and click on the download link in the SDK column. That will take you to a page

that gathers some optional information. Click on the download link again and you will go to another page with a license agreement. If you click on ACCEPT button and then click on
Download j2sdk-1_4_1_03-windows-i586.exe an executable file will be delivered to your

computer. This files about 38 MB in size and takes 15-20 minutes to download on a fast internet connection. To install the Java JDK, simply click on the j2sdk-1_4_1_03- icon to install the Java JDK. DOWNLOADING TEXTPAD The other thing you need to develop programs at home is a text editor. Any text editor will do but there is one in particular, called TextPad that can also be used to compile and run Java programs assuming that you have installed a Java SDK. It is shareware and can be downloaded from the following site: http://www.textpad.com Shareware is not free. You can download it and test-drive it

3

HISTORY Around 1990, James Gosling, Bill Joy and others at Sun Microsystems began developing a language called Oak. The wanted it primarily to control microprocessors embedded in consumer items such as cable set-top boxes, VCR's, toasters, and also for personal data assistants (PDA). To serve these goals, Oak needed to be:
o o o

Platform independent (since multiple manufacturers involved) Extremely reliable Compact.

However, as of 1993, interactive TV and PDA markets had failed to take off. Then the Internet and Web explosion began, so Sun shifted the target market to Internet applications and changed the name of the project to Java. By 1994 Sun's Hot Java browser appeared. Written in Java in only a few months, it illustrated the power of applets, programs that run within a browser, and also the capabilities of Java for speeding program development. Riding along with the explosion of interest and publicity in the Internet, Java quickly received widespread recognition and expectations grew for it to become the dominant software for browser and consumer applications. However, the early versions of Java did not possess the breadth and depth of capabilities needed for client (i.e. consumer) applications. For example, the graphics in Java 1.0 seemed crude and clumsy compared to mature software developed with C and other languages. Applets became popular and remain common but don't dominate interactive or multimedia displays on web pages. Many other "plug-in" types of programs also run within the browser environment.

4

smart cards with additional features provided by Java.a compiler. Sun also provides a runtime bundle with just the JVM when the programming tools are not needed. transactions processing. Sun provides a set of programming tools such as javac.So Java has not succeeded at development of consumer applications.. applications such as on line web stores. have been sold as of the summer of 2004. Over 600 million Java Cards. transforms the Java language source code to byte code that runs in the JVM. or middleware. many JVMs have been written by groups outside of Sun.. and so forth. Java is now used in several hundred cell phone models. such as Sun's javac. compilers of other languages have been created that output byte code to run in the JVM. DEFINITION The term Java actual refers to more than just a particular language like C or Pascal. 5 . that runs on a given platform and takes the byte code programs as input and interprets them just as if it were a physical processor executing machine code. For example. etc. just as many different languages can create machine code for a given processor. However. Java has also become quite common on small platforms such as cell phones and PDAs.  Java Virtual Machine (JVM) – a program.  Java byte code . including:  A high level language – the Java language is a high level one that at a glance looks very similar to C and C++ but offers many unique features of its own. database interfaces. Java's capabilities grew with the release of new and expanded versions (see below) and it became a very popular language for development of enterprise. Linux. java and others in a bundle that it calls a Java Software Development Kit for each version of the language and for different platforms such as Windows. Java encompasses several parts. such as Sun's java. Similarly.

Detailed specifications and source code are made openly available.1 JVM that it used in its Internet Explorer browser. Sun sued Microsoft and the dispute was later settled out of court. class packages. Open or Closed? Java is not quite an open language but not quite a proprietary one either. For example. All the core language products . however. Sun. JAVA PROCEDURE The essential steps to creating and running Java programs go as follows:    Create a Java source code file Compile the source code Run the compiled code in a Java Virtual Machine. Other companies and organizations can legally create a clean sheet compiler and/or a Virtual Machine as long as it follows the publicly available specifications. 6 . Microsoft did this with the Version 1.compiler. Microsoft's VM differed in a some significant details from the specifications and Sun accused Microsoft of attempting to weaken Java's "write once. virtual machines (VM). run anywhere" capabilities.Java. The Java Community Process (JCP) leads the development of new standards for the language.are free. and trademarks. and other components . does still assert final say on the specifications and controls the copyrights to logos.

With the javac program. java.The following figure illustrates these steps: Figure: Steps for creating and running a Java program. 7 . Here the output is Test. In the figure the class name is Test so you must therefore save it to the file name Test. The first part of the name must match the class name in the source code. java This creates a byte code file (or files if the code file included more than one class) that ends with the "class" type appended. You create the code with a text editor and save it to a file with the ".java" suffix. class. We will discuss what class actually means in later chapters. All Java source code files must end with this type name. you compile this file as follows: C :> javac Test.

The JVM is an interpreter program that emulates a processor that executes the byte code instructions just as if it were a hardware processor executing native machine code instructions. The Java byte code can then run on any platform in which the JVM is available and the program should perform the same. you run this file as follows: C :> java Test 8 . The platform independence of Java thus depends on the prior creation of JVMs for different platforms. There are now Java processors that directly execute the byte codes directly in hardware.The byte code consists of the instructions for the Java Virtual Machine (JVM or just VM). This Write Once. With the class file. Run Anywhere approach is a key goal of the Java language.

INTERFACES Programming with Interfaces Separating Interface and Implementation Simple Relatable Interface Using a Interface as Type Rewriting Interfaces 39 29 11 9 .CONTENTS 1. PACKAGES Introduction Java Package User-defined Package 3. SIMPLE JAVA APPLICATIONS & STRING HANDLING Hello World Java class Reading Text from Standard Input Reading an Input from Console Handling SubString String Tokenizer String versus String Buffer Reverse a Word toString Program Beep and Date Program 2.

EXCEPTION HANDLING Introduction Handling of Exceptions User-defined Exceptions Trace Class Reraise Class 6.4. THREADS Java Threads Simple Java Thread Program A Counter Class The Thread_Ex Class Locks Grained Locks Semaphores 5. JDBC What is JDBC? Using a JDBC driver Connecting to Database Structuring Statement Parsing a text file into a Database table Processing a Result Set Printing a Database Table 51 62 77 10 .

Chapter 1 A SIMPLE JAVA APPLICATION AND STRING HANDLING Objectives       Understanding classes and their contents Understanding objects and their creations Object initializations using constructors Getting Input from User Understating String Manipulation To implement String Tokenizer 11 .

out.java 12 . } } Save this code in a file called HelloWorldApp.java Step 2: Compile the application with the command line:  javac HelloWorldApp.println ("Hello World!").The following steps involved to create a simple java program Step 1: Use an editor to enter the following code for the Hello Word App program: HelloWorldApp Application Public class HelloWorldApp { public static void main (String arg []) { System.

Import java.IOException.out..class Step 3: Use the java command to run the program:  Java HelloWorldApp Hello World! The output is printed after the command line. READING TEXT FROM STANDARD INPUT Import java.This creates the class file (with the byte code output): HelloWorldApp.io.BufferedReader. } Private static void doReadFromStdin() { try { BufferedReader in Stream = new Buffered Reader ( New InputStreamReader(System. String inLine = "".io.println (“processing. Import java.InputStreamReader.. > “+ str + "\n"). 13 . Public class ReadFromConsole { Private static void process (String STR) { System.io. in) ).

} } READ AN INPUT FROM CONSOLE import java.equalsIgnoreCase("exit")) ) { System.println("IOException: " + e). process(inline).While (! (inLine. Public class ReadIntFromConsole { private static void doReadIntFromConsole() { String inline = null.equalsIgnoreCase ("quit")) && !(inLine. InLine = inStream.io. 14 .out. Int check Integer = 0.print("prompt> ").readLine ().out. } } catch (IOException e) { System.*. } } Public static void main (String[] args) { doReadFromStdin().

Inline = inStream.println("You did not enter a valid Integer: " + inline). System.out. return. the *. } catch (IOException e) { System.Try { Buffered Reader in Stream = new BufferedReader ( new InputStreamReader(System. Return. } catch (NumberFormatException nfe) { System.println("IOException: " + e). compilation. Check Integer = Integer.print("Enter a valid Integer and hit <ENTER>: "). creating applets and running applications.readLine(). } Public static void main (String [] args) { doReadIntFromConsole().e.println("You entered a valid Integer: " + checkInteger). 15 .parseInt(inline).java files). } } EXERCISE Completion of the following simple exercises will insure that you have successfully installed your JDK and know the basic mechanics of creating source code files (i. } System.out.out.out.in) ).

For example the String "Hello" is a five element array. int length) Public String(byte bytes []) public String (StringBuffer buffer) index methods METHODS public int length () public int indexOf (int ch) 16 . 01234 Hello CONSTRUCTORS Public String () Public String (String value) Public String (char value []) public String(char value[].String. int length. 'e' is character 1. This class has many methods that are useful for working with strings. String enc) Throws UnsupportedEncodingException Public String (byte bytes []. Strings begin counting at 0. into count) public String(byte bytes[]. Specifically they're instances of the class java.lang. and so on. Internally Java Strings are arrays of Unicode characters.1. STRING HANDLING INTRODUCTION Strings are objects. int offset. String enc) throws UnsupportedEncodingException public String(byte bytes[].String package. into offset. Like arrays. Thus in the String "Hello" 'H' is character 0. int offset. Create your own application program that prints out your name to the command line. The String class is included in the java.lang.

int fromIndex) public int lastIndexOf(String str) public int lastIndexOf (String str. COMPARISONS public boolean equals (Object anObject) public boolean equalsIgnoreCase(String anotherString) public int compareTo(String anotherString) 17 . char dst []. int fromIndex) public int lastIndexOf (int ch) public int lastIndexOf (int ch. int count) public static String copyValueOf (char data []. int count) public static String copyValueOf (char data []) public static String value Of (boolean b) public static String valueOf(char c) public static String valueOf (int i) public static String valueOf (long l) public static String valueOf (float f) public static String valueOf (double d) substring () methods public char charAt (int index) public void get Chars (int srcBegin.public int indexOf (int ch. int srcEnd. Ends are exclusive. int fromIndex) valueOf () methods public static String valueOf (char data []) public static String valueOf (char data []. int fromIndex) public int indexOf (String str) public int indexOf (String str. int dstBegin) public byte[] getBytes(String enc) throws UnsupportedEncodingException public byte [] getBytes () public String substring (int beginIndex) public String substring(int beginIndex. int offset. int endIndex) public String concat(String str) public char [] toCharArray () Beginnings are inclusive. int offset.

out.substring (13. 12). int ooffset. String b = a.substring (5. System. int len) public boolean regionMatches (boolean ignoreCase. substring (13. int toffset.println ("a. System. System.println("Original string: " + a). System.Substring (5): " + b).println ("a.out. char newChar) public String toLowerCase (Locale locale) public String toLowerCase () public String toUpperCase (Locale locale) public String toUpperCase () public String trim () Substring Public class Substring { private static void doSubstring () { String a = "Alex Michael Hunter".substring (5).out.a. a. String d = a. int toffset) public boolean startsWith (String prefix) public boolean endsWith (String suffix) Modifying Strings public String replace (char oldChar. String c = a. String other.length ()).public boolean regionMatches (int toffset.out.substring (5. String other.length ()): " + d). 12): " + c). int len) public boolean startsWith(String prefix. 18 . int ooffset.println ("a.

printResults2 ("A||C|D”.System. process2 ("A|B|C|D")). } System. Public class String TokenizerDemo { private static void doStringTokenizer1 () { String a = "Alex Michael Hunter". printResults2 ("A|||D|E”.out. } } STRING TOKENIZER import java.*.println().println ("Original string : " + a).println (). process2 ("A||C|D")). 19 .out. While (st. } Public static void main (String [] args) { doSubstring().println ("-------------------------").out. System.println ("Token: " + st. process2 ("A|||D|E")). System. } private static void doStringTokenizer2 () { printResults2 ("A|B|C|D”.out.nextToken ()).util.out. StringTokenizer st = new StringTokenizer (a).hasMoreTokens ()) { System.

// Unless you ask StringTokenizer to give you the tokens.equals (DELIM)) { if (i++ >= MAXFIELDS) { // This is messy: A vector would be better to allow any // number of fields Throw new IllegalArgumentException ( "Input line " + line + " has too many fields").println ("Output " + i + " was: " + outputs[i]).hasMoreTokens ()) { String s = st. } } private static String [] process2 (String line) { int MAXFIELDS = 5. i<outputs. for (int i=0.length. String [] outputs) { System. = "|". StringTokenizer st = new StringTokenizer(line. DELIM. true). // Stuff each token into the current user while (st. } 20 . int i = 0.} private static void printResults2 (String input.nextToken (). if (s.out. it silently // discards multiple tokens. String DELIM String [] results = new String [MAXFIELDS]. i++) { System.println("Input: " + input).out.

When a String is being manipulated in code. doStringTokenizer2 (). The String Buffer class. on the other hand. 21 . The significant difference between these two classes is performance where String Buffer is faster than String when performing simple concatenations. name += ". character string is routinely Concatenated like shown in the following example: String name = new String ("Alex"). is used to represent characters that can be modified. Hunter".continue. The String class is used to store and manipulate character strings that cannot be changed. } } STRING BUFFER VERSUS STRING: Java provides two classes: String and String Buffer. } public static void main (String [] args) { doStringTokenizer1 (). Now consider the same concatenation. Another Way of describing this is to say that Strings are read only and immutable. but using a String Buffer: String Buffer name = new String Buffer ("Alex"). } Results[i] = s. } // while return results.

lang.append (".String> 3 dup 4 ldc #3 <String "Alex"> 6 invokespecial #4 <Method java.String(java. Lets examine the generated byte code from our two examples. public static void main (java.lang.lang.String)> 21 ldc #8 <String ".lang.lang.lang.lang.java public class t extends java.String []).StringBuffer append(java.Object ()> 4 return Method void main (java. } Method t () 0 aload_0 1 invokespecial #1 <Method java.StringBuffer> 13 dup 14 invokespecial #6 <Method java. The byte code for the example using String looks like this: % javap -c t //Compiled from t. the examples above may seem very similar.lang. Hunter").String []) 0 new #2 <Class java.lang. Now to many developers. To discover why this is the case.StringBuffer()> 17 aload_1 18 invokevirtual #7 <Method java.lang.name. Using a String Buffer for concatenation can in fact produce code that is significantly faster than using a String. Hunter"> 22 .Object { public t (). The + operator appears innocent.String)> 9 astore_1 10 new #5 <Class java. but the code generated may produce some surprises.lang.

namely: String name = new String("Alex").StringBuffer append(java. After the concatenation is performed on the String Buffer object. This method creates a new String object from the Temporary String Buffer object. Then.) A String Buffer object at location 10 23 . and it’s append Method is called at location 23.) A String object at location 0 2. The byte code generated for the Concatenation creates a String Buffer object. Hunter". the two lines of code above result in the creation of three Objects: 1. Because the String class is immutable. the byte code at location 10 through 29 is executed for the concatenation: name += ".lang. it must be converted back into a String.String)> 26 invokevirtual #9 <Method java.lang. then invokes it’s append method: The temporary String Buffer object is created at location 10.String toString()> 29 astore_1 30 return The byte code at locations 0 through 9 is executed for the first line of code. The creation of this temporary String Buffer Object and its subsequent conversion back into a String object are very expensive.23 invokevirtual #7 <Method java. a String Buffer must be used for concatenation. This is done with the call to the toString Method at location 26. Here is where things get interesting. In summary.lang.

let's look at the byte code generated for the example using String Buffer: % javap -c t //Compiled from t.java public class t extends java.3.lang.lang.StringBuffer(java.String)> 9 astore_1 10 aload_1 11 ldc #5 <String ". } Method t() 0 aload_0 1 invokespecial #1 <Method java.String)> 16 pop 17 return The byte code at locations 0 to 9 is executed for the first line of code: String Buffer name = new String Buffer ("Alex"). public static void main (java.lang.String[]). String Buffer appends (java. The byte code at location 10 to 16 is then executed for the concatenation: 24 .lang.Object ()> 4 return Method void main (java. Hunter"> 13 invokevirtual #6 <Method java.Object { public t ().lang.lang.lang.) A String object at location 26 Now.StringBuffer> 3 dup 4 ldc #3 <String "Alex"> 6 invokespecial #4 <Method java.String[]) 0 new #2 <Class java.lang.lang.

If the functionality of the String class is desired.println("nameStr2 : " + nameStr2). consider using a String Buffer for concatenation and then performing one Conversion to String. String nameStr2 = new String (name). Unlike the first example. there is no need to create a temporary String Buffer and then convert it into A String object. Hunter"). // allocates a new string that contains the sequence of characters // currently contained in the string buffer argument. at location 0. Hunter").toString ().println("nameStr1 : " + nameStr1). as is the case in the first example. System. Append (". 25 .out. This code creates only one object. however.out.out. Notice that.name. String Buffer concatenation is significantly faster than String Concatenation. Obviously. Name. the String Buffer. append (". System. this code invokes the append method of a String Buffer object. String Buffers should be used in this type of Operation when possible.println("name : " + name). System. Public class StringBufferDemo { public static void main (String [] args) { StringBuffer name = new String Buffer ("Alex"). To summarize. // One way to convert a String Buffer to a String String nameStr1 = name.

} System.*.util.out.print("Reverse word string: ").} } REVERSE STRING – WORD import java.out.print (" ").push (tempStringTokenizer. StringTokenizer tempStringTokenizer = new StringTokenizer (a). Stack stack = new Stack (). System.println("\nOriginal string: " + a). System.out. while(!stack.println("\n"). } 26 .empty()) { System. } System. while (tempStringTokenizer. public class StringReverseWord { private static void doStringReverseWord() { String a = "Alex Michael Hunter".out.pop ()).nextElement ()).out.print (stack.hasMoreTokens()) { stack.

27 .out. } } TO STRING Used to provide an example of how to utilize how to format objects using the toString () method. } public String to String () { return "Object members => [ x=" + x + ". or when involved in a string concatenation. 20).y = yIn. y=" + y + " ]". The toString () method is called whenever an object is being passed to System. int yIn) { this. } public static void main(String[] args) { ToStringExample a1 = new ToStringExample(10. public ToStringExample (int xIn. this. int y.public static void main (String [] args) { doStringReverseWord(). public class ToStringExample { int x.println (). any other equivalent method.x = xIn.

out.println (new Date () + "\007"). } } 28 .System.out.*.println (a1).util. } } BEEP AND DATE import java. public class BeepDate { public static void main (String [] args) { System.

Chapter 2 PACKAGES Objectives    Understanding Java Package Accessing the class members in a Package Package Implementation PACKAGES A Java package is a mechanism for organizing Java classes into namespaces similar to the modules of Modula. Classes in the same package can access each other's protected members. allowing classes to download faster as a group rather than one at a time. 29 .    A package provides a unique namespace for the types it contains. A package can contain the following kinds of types. Programmers also typically use packages to organize classes belonging to the same category or providing similar functionality. Java packages can be stored in compressed files called JAR files. Java source files can include a package statement at the top of the file to designate the package for the classes the source file defines.

event. java. After either of these import statements.awt. Imports only the Action Event class from the package. while import java.awt.awt.ActionEvent(). The statement import java. the package that the file belongs to is specified with the package keyword. For example. imports all classes from the java.event.o o o o Classes Interfaces Enumerated types Annotations Using packages In Java source files. it is convenient to import the classes from the package with an import statement.event. Doesn’t require a preceding import statement.ActionEvent.event. Package java.awt. Classes can also be used directly without an import statement by using the fully-qualified name of the class.event package. 30 .awt.event. To use a package inside a Java source file.awt.ActionEvent myEvent = new java.*. the Action Event class can be referenced using its simple class name: Action Event my Event = new Action Event ().

[edit] Creation of JAR files JAR Files are created with the jar command-line utility. The naming conventions describe how to create unique package names. with levels in the hierarchy separated by periods (. protected nor private access modifier is specified in the declaration.jar. This allows packages to be separately. The ' c ' option on the command line tells the jar command to "create new archive. so that packages that are widely distributed will have unique namespaces. classes in other packages cannot access classes and members declared with default access. easily and automatically installed and catalogued.class Compresses all *. The Java Language Specification establishes package naming conventions in order to avoid the possibility of two published packages having the same name. a package name begins with the top level domain name of the organization and then the organization's domain and then any sub domains listed in reverse order. there is no semantic relationship between packages. By contrast. Although packages lower in the naming hierarchy are often referred to as "sub packages" of the corresponding packages higher in the hierarchy. The file's name comes next before the contents of the JAR file. Default access is enforced when neither the public. In general. The 31 . The command jar cf myPackage." The ' f ' option tells it to create a file.jar *. Class members declared as protected can be accessed from the classes in same as well as classes in other packages that are subclasses of the declaring class.) (Pronounced "dot"). [edit] Package naming conventions Packages are usually defined using a hierarchical naming pattern.class files into the JAR file myPackage.[edit] Package access protection Classes within a package can access classes and members declared with default access and class members declared with the protected access modifier.

mysoft.0 java.awt — Java Database Connectivity (JDBC) to access databases — basic hierarchy of packages for native GUI components javax.mysoft.fractions distinguishes the fractions package from another similar package created by another company.nio java. If a US company named My Soft also creates a fractions package. sockets. encryption and decryption java..sql java.math java. 32 .swing — hierarchy of packages for platform-independent rich GUI components Many implementations of Java use a hierarchical file system to manage source and class files.fractions. then the classes in these two packages are defined in a unique and separate namespace. if an organization in Canada called My Soft creates a package to deal with fractions.net — basic language functionality and fundamental types — collection data structure classes — file operations — multiprecision arithmetics — the New I/O framework for Java — networking operations. [edit] Core packages in J2SE 6.lang java. Package names should be all lowercase characters whenever possible. but names it us..organization can then choose a specific name for their package. java. . For example. naming the package ca.util java.security — key generation.io java. DNS lookups.

java -.Import Packages   Access.access to predefined packages user defined packages 33 .

*.java -.io. tools.println (Math. o tools.lang" 3 public class Access { 4 5 6 7 8 9 10 11 12 13 14 System.Hammer().lang" // "out" is class variable of type "java.id ().illustrate access to predefined packages 2 // No import statement required for package "java.Wrench().java 1 // Pack.PI).java 34 .Wrench crescent = new tools.out.The Java Program: Access.illustrate the use of user-defined packages 2 import tools. 3 public class Pack { 4 5 6 7 8 9 10 } } public static void main (String args []) { tools. crescent.Hammer. } } // class "Math" is also defined in package "java.PrintStream" // "println" is an overloaded method in class "PrintStream" The Java Program: Pack.id ().Hammer claw = new tools. claw.java -.java 1 // Access.lang" // "PI" is a constant class variable of type "double" public static void main (String args []) { // class "System" is defined in package "java.

java tools/Hammer.part of tools package illustrating packages 2 package tools. java 1 // Hammer.out.java -.java java Pack Access specifiers    private -.accessible anywhere the class is accessible.out.accessible (inherited) by subclasses.} 5} o tools. 3 public class Hammer { 4 public void id () {System.part of tools package illustrating packages 2 package tools. so-called "package" access -. and accessible by code in same package  public -. and inherited by subclasses Notice that private protected is not syntactically legal.} 4} o   javac Pack.java -.accessible only in the class no modifier.The Java Program: tools/Hammer.java 1 // Wrench.java tools/Wrench. 35 .java The Java Program: tools/Wrench. 3 public class Wrench { 4 public void id () {System.Wrench.println ("Wrench") .accessible only in the same package protected -.println ("Hammer") .

Summary of access to fields in Java access by the class itself a subclass in same package non-subclass in same package a subclass in other package non-subclass in other package Example  private "package" protected public yes no no no no yes yes yes no no yes yes yes yes no yes yes yes yes yes One/Main. it is not public 5 // Can't import "one. 2 3 import another. protected int z. // can access "one. one.Unrelated" public static void main (String args[]) { } . 4 // Can't import "another. public int x. Unrelated u. private int y. c. same name as in "another" 6 public class Main { 11 12 13 14 15 17 18 19 20} 21 class Sub extends Main { 22 23 private int d = a. java The Java Program: one/Main. b.AlsoSub". private int e = z.Unrelated uu. // can access "package" variables // can access protected variables of "Main" 36 int a.Unrelated. java 1 package one.Unrelated".

// can access protected variables of "Main" 10 }  one/Unrelated.java java one. dir1/dir2/A/B/C.a. // can access public methods of "Main" private int j = z.z. 2 import one. private int f = m. 3 class Unrelated { 4 } javac one/Main.java another/Unrelated.Main Classes in the same package can be in different directories.java The Java Program: one/Unrelated.java The Java Program: another/Unrelated.x.java 1 packages another. 3 class AlsoSub extends Main { 4 5 6} 7 public class Unrelated { 8 9 private Main m = new Main().java 1 // Same name as the class in package "another"! 2 package one. // can access "package" variables private int g = m.class 37 . private int h = m. // can access protected variables of "Main" another/Unrelated.Main.24 } 25 class AlsoUnrelated { 26 27 28 29 }  private Main m = new Main(). // can only access public methods of "Main" private int i = x.

util. You can accidentally use the wrong classes. // also import java.util.. Packages are simple-minded in Java and dangerous. } 38 .*.Date public class Collision { Hash Map m. Java will not detect it. Date d..sql. import java. So if you misspell a class name and there happens to be a class by that name in the same directory.class java -classpath dir1/dir2:dir3 . // imports java.dir3/A/B/D.util.*.Date import java.

In its most common form. the buttons on the front of your television set. objects define their interaction with the outside world through the methods that they expose. if specified as an interface. might appear as follows: Interface Bicycle { Void change Cadence (int new Value). an interface is a group of related methods with empty bodies. You press the "power" button to turn the television on and off. for example. Methods form the object's interface with the outside world. are the interface between you and the electrical wiring on the other side of its plastic casing. A bicycle's behavior.Chapter 3 INTERFACE Objectives     Need for Interface Java Interface Separation of Interface from Implementation Using Interface as Type What Is an Interface? As you've already learned. 39 .

Interfaces form a contract between the class and the outside world. boolean greater(Object m).void change Gear (int new Value). Programming with Interfaces in Java In Java an interface is similar to an abstract class in that its members are not implemented. There is no code at all associated with an interface. } 40 . In interfaces. For example. all methods defined by that interface must appear in its source code before the class will successfully compile. the name of your class would change (to ACME Bicycle. and this contract is enforced at build time by the compiler. boolean lessEqual (Object m). void applyBrakes (int decrement). _none_ of the methods are implemented. from my personal library: public interface Comparable { boolean less(Object m). for example). If your class claims to implement an interface. boolean greaterEqual (Object m). Void speedup(int increment). } To implement this interface. and you'd use the implements keyword in the class declaration: Class ACME Bicycle implements Bicycle { // remainder of this class implemented as before } Implementing an interface allows a class to become more formal about the behavior it promises to provide.

.) There are almost no disadvantages to multiple inheritance of interface (small name conflict problems are one exception). I can't find this in the documentation..All instance methods are implicitly public and abstract..} . These include efficiency considerations as well as the semantic difficulty of determining just what code will be executed in some circumstances. There are large disadvantages to multiple inheritance of implementation as in C++. } boolean greater Equal (Object m) {. . but are discouraged from doing so as the marking is considered obsolete practice. An interface creates a protocol that classes may implement. Also. however. One can actually extend several interfaces. Interfaces thus enjoy the benefits of multiple inheritances. I expect that an abstract class can choose to implement part of an interface leaving the rest for non-abstract subclasses. Note that one can extend an interface (to get a new interface) just as you can extend a class.} boolean greater(Object m){ . The interfaces themselves need not be public and several interfaces in the standard libraries are not public and thus used only internally. The Polynomial class that implements Comparable will need to implement all of the functions declared in the interface. } boolean lessEqual (Object m) { . . . (Classes do not. construct a simple example and try it to see if the compilers accept it. . Anyone that needs to know can. A class that implements an interface must provide bodies for all methods of that interface. . public class Polynomial implements Comparable { . . I call this 41 . } Polynomial multiply (Polynomial P) {. You can mark them as such. . . . boolean less (Object m) {. } A class may choose to implement any number of interfaces.. . of course.

Other instance methods of objects passed. or in general. Any function can have parameters that are of interface type. Note that classes implementing Comparable don't need to be otherwise related to each other. You can actually use variable syntax for defining them (with initializes. class Foo { Vector bar (Vector v. since compilers should differ very little. The usefulness of interfaces goes far beyond simply publishing protocols for other programmers. This means that a class that uniformly uses an interface type for some method parameters. They may also be passed to methods that name that interface as a parameter type. These variables may refer to any object from any class that implements the interface. } One can apply bar to a Vector and a Polynomial. such as the multiply method from Polynomial cannot be used within bar. of any interface type. Comparable c) {. 42 . Note that interface declarations never declare variables. They will be constants in any case..technique "probing" and use it often when I'm not sure about how something works. since Polynomial implements Comparable. The body of instance method (member function) bar will only be able to apply Comparable methods to parameter c. Any object from a class that implements the interface may be passed as an argument.} . this should be an even more valuable technique.. In Java. You don't need to say "static final" though you may.. We can also have variables (not just parameters) of type Comparable. with its more complete definition than other languages. behaves very much like a class template in C++. Dynamic Binding assures that the actual class methods for the object passed will be applied. Therefore the bar function is polymorphic in its second parameter as many actual types may be passed for this value. of course).. These variables may have only members defined within the interface applied to them however. though they may declare constants.

One of the very important interfaces in Java (in package java. then at runtime the ClassCastException will be thrown. We name the interface and the interface defines a list of requirements that the objects must implement.. If you need to check the type of any reference. It won't fix up problems. you can use the instance of operator. Enumeration e =. that adhering to an interface requires saying that the class implements it in its class header. In Java we have the advantage that such interfaces are explicit. It simply affirms what must otherwise be true. Notice that C++ templates are a form of _implicit_ interface.If you have a variable of some interface type and you know that it refers to an object of a specific class. then just use type Object rather than an interface type.util) is interface Enumeration { boolean hasMoreElements (). 43 next Element(). Note.. Note that cast can never make an incorrect program correct. If you apply operator< to such a parameter. then the actual argument needs to support operator<. Object } If an object implements Enumeration. Just think of the interface names as if they were template arguments. however. therefore. we can use the object to control a while loop. If a "template" puts _no_ restrictions on an object. A run-time check will be inserted to guarantee correctness. A method in Java that has a parameter of interface type is nearly the same as a function template in C++. If you find yourself using it often. the uses of that name impose requirements on the actual arguments that can be used to instantiate the template. and the power of the dynamic binding principle. explicit rather than implicit as with C++ templates. then you can cast it to Polynomial. Use of instance of should be rare. When you define a class template in C++ and then use the template parameter in the body of the class. say Polynomial. Adherence to interfaces is. If you cast a reference incorrectly. you haven't yet absorbed object-oriented programming. . A class that uses interfaces to type any variables or parameters behaves very similarly to a class template in C++.

An interface can extend any number of interfaces. Collection objects like stacks and hashtables return enumeration objects so that we can process all elements of the collection with a while loop without needing access to the internal storage mechanism of the collection. That returns an enumeration over the elements of the Vector.while (e. Summary A class can extend one other class and implement any number of interfaces. for example has an instance method public final synchronized Enumeration elements (). Note that one mechanism in Java (interfaces) supports most of the functionality of two mechanisms of C++ (templates and multiple inheritances). When a class implements an interface it implements all of the methods declared in that interface.elements(). Therefore to print all elements in Vector V. When you create a new container type (like Vector) you also create a class that implements Enumeration so that users can get access to the elements of the container for such processes.nextElement ()). and that hasMoreElements will be true if and only if not all elements have yet been returned by next Element. To implement an enumeration properly.nextElement ()).hasMoreElements ()) println ("Value is” + e. You can have variables and parameters of an interface type. One of the designers of C++ has stated that if templates had been added to C++ earlier then multiple inheritances probably 44 .hasMoreElements ()) doSomethingWith (e. Enumerations are called iterators in other languages. you must guarantee that each call of next Element will return an element of the collection not yet returned. you can write Enumeration e = V. Vector. You can also cast these as needed. while (e.

In contrast to the notion of Interface in Java. and may provide implementations for the interface as well. we propose a different separation of interface and implementation. This is because templates and multiple inheritances can be used to solve many of the same problems. In C++. Classes are insatiable.would not have been seen as needed. a dynamic version of static virtual function tables. The use of the tables will support fast method lookup. A met object protocol (MOP) is an interface that allows a programmer to customize properties of the programming language. while a Class defines the structure and behavior of its instances. not just for subclasses but for the base class itself. In a language such as Java all methods are assumed virtual (unless declared final) and all objects are referenced through pointers. Separating interface and implementation There have been various proposals for separating an interface from an implementation. In contrast. while interfaces are not. based on the properties supported by the context relation. For example the language Java supports this separation An Interface defines a set of method signatures. dynamic binding is required when a virtual method is invoked through a pointer. a base class that defines only interfaces may still be instantiated. The context relation allows method update. if it implements the methods defined by each interface. If an implementation of a method is not provided directly in the base class. although it would be possible to add a keyword to limit dynamic lookup such as the final keyword in Java. A class may match several interfaces. to avoid pointer chasing through lists of context objects. we assume all methods to be context-updatable. Dynamic binding occurs regardless of whether a method is invoked through a pointer or variable. the implementation may be separately given in one or more classes that are context-related to the base class. we require an implementation of the method to either exist directly in the base class or to exist in some context-related class that is declared to be the default implementation. such as adding persistence and concurrency A 45 . A base class defines the structure and interface (method signatures) of its instances. For simplicity. To prevent a method resolution error at run-time. We propose the use of context tables.

it could be number of characters. Implementing the Relatable Interface Here is the Rectangle class that was presented in the Creating Objects section. while volume would work for three-dimensional geometric objects. 46 . the class that instantiates them should implement Relatable. Any class can implement Relatable if there is some way to compare the relative "size" of objects instantiated from the class.reflective programming language is one which supports such customizations. For planar geometric objects. -1 if this is greater // than. for books. or less than other public int isLargerThan(Relatable other). A Sample Interface. then you know that you can compare the size of the objects instantiated from that class. For strings. it could be number of pages. All such classes can implement the isLargerThan() method. no matter what they are. for students. } If you want to be able to compare the size of similar objects. Relatable Consider an interface that defines how to compare the size of objects. equal to. area would be a good choice (see the RectanglePlus class that follows). 0. allowing the program to reason about its own execution state and alters behavior accordingly The context relation and context objects can be implemented using reflection. it could be weight. If you know that a class implements Relatable. and so forth. public interface Relatable { // this (object calling isLargerThan) and // other must be instances of the same class // returns 1. rewritten to implement Relatable.

} // a method for moving the rectangle public void move(int x. } public RectanglePlus(Point p. int h) { origin = p. int y) { origin. if (this.x = x. } // a method to implement Relatable public int isLargerThan(Relatable other) { RectanglePlus otherRect = (RectanglePlus)other. // four constructors public RectanglePlus() { origin = new Point(0. int w. width = w. int h) { origin = new Point(0. height = h. public Point origin. } public RectanglePlus(Point p) { origin = p.y = y. 0). public int height = 0. } public RectanglePlus(int w.getArea()) 47 . height = h.getArea() < otherRect. origin. } // a method for computing the area of the rectangle public int getArea() { return width * height. 0). width = w.public class RectanglePlus implements Relatable { public int width = 0.

You can use interface names anywhere you can use any other data type name. If you define a reference variable whose type is an interface. the objects instantiated from any of those classes can be compared with the findLargest() method— provided that both objects are of the same class.getArea() > otherRect. Similarly. else if (this. it can invoke the isLargerThan method. Object object2) { Relatable obj1 = (Relatable)object1. If you make a point of implementing Relatable in a wide variety of classes.isLargerThan(obj2) > 0) return object1.getArea()) return 1. here is a method for finding the largest object in a pair of objects. if ( (obj1). for any objects that are instantiated from a class that implements Relatable: public Object findLargest(Object object1. } By casting object1 to a Relatable type. Relatable obj2 = (Relatable)object2.return -1. you are defining a new reference data type. Using an Interface as a Type When you define a new interface. else return object2. else return 0. } } Because RectanglePlus implements Relatable. they can all be compared with the following methods: 48 . the size of any two RectanglePlus objects can be compared. As an example. any object you assign to it must be an instance of a class that implements the interface.

int doSomethingElse(String s). boolean didItWork(int i. where they can have behavior from both a superclass and an interface. no matter what their class inheritance is. Rewriting Interfaces Consider an interface that you have developed called DoIt: public interface DoIt { void doSomething(int i. so that the interface now becomes: public interface DoIt { void doSomething(int i. } Suppose that. String s).public Object findSmallest(Object object1. Relatable obj2 = (Relatable)object2. This gives them some of the advantages of multiple inheritance. double x. 49 . int doSomethingElse(String s).isLargerThan(obj2) < 0) return object1. else return false. if ( (obj1). Object object2) { Relatable obj1 = (Relatable)object1. you want to add a third method to DoIt. } public boolean isEqual(Object object1. at a later time. double x). When they implement Relatable. Object object2) { Relatable obj1 = (Relatable)object1. else return object2. they can be of both their own class (or superclass) type and a Relatable type. Relatable obj2 = (Relatable)object2.isLargerThan(obj2) == 0) return true. if ( (obj1). } These methods work for any "relatable" objects. double x).

Programmers relying on this interface will protest loudly. all classes that implement the old DoIt interface will break because they don't implement the interface anymore. Try to anticipate all uses for your interface and to specify it completely from the beginning. 50 .} If you make this change. Given that this is often impossible. you may need to create more interfaces later. double x. For example. String s). } Now users of your code can choose to continue to use the old interface or to upgrade to the new interface. you could create a DoItPlus interface that extends DoIt: public interface DoItPlus extends DoIt { boolean didItWork(int i.

and is not allowed to throw 51 . takes no arguments. Run () is declared to be public. For instance. every thread begins by executing a run () method in a particular object. If your computer does not have multi-processors then the threads really do not run concurrently. in Java the garbage collector thread runs in the background. a paint () method is not invoked directly by the applet but by a thread in the interpreter. But the idea is that while the screen is waiting for some input some other process can be running.Chapter 4 THREADING Objectives      Understanding Threads Thread_Ex Class Synchronization Locks and Grained Locks Semaphores JAVA THREADS Threads are an integral to the Java language. has no return value. In Java. If you remember. Whenever the program is waiting on something. A thread is similar to a process but that multiple threads run in the same address space as the application. Java might invoke the garbage collector to free up space. Multiple threads can be used to run different parts of your program simultaneously.

Counter 1 thread 3. The structures used for this simplification is based on monitors.any exceptions. The first example that we will be examining is called thread_ex. In this example. If the user clicks on a button. which is a popular scheme developed by C. then the other threads must wait for that thread to finish in order acquiring the lock. If the user clicks on that same button again. A SIMPLE JAVA THREADS EXAMPLE In this section of the tutorial.R. The update thread is a thread that will handle updating the display. After a count of 50 for each counter has been reached. THE THREAD_EX APPLET Counter class source thread_ex class source THE COUNTER CLASS 1: class Counter extends Thread { 2: /* This class simply runs a thread to count to 50 */ 52 . A monitor is a lock that only one thread can access at a time. we are going the play with threads. Any class can implement a run () method by declaring that the class implements the Runnable interface. We will have two numbers display and two buttons displayed (one for each counter thread). Java also simplifies the synchronization of threads. the application is done. The button is a toggle switch for the thread to run or not run. Update thread The counter threads are threads that simply count from 1 to 50. we will spawn three threads:    1.A. Counter 0 thread 2. If one thread holds the lock. Hoare. the counting will stop and that thread will be suspended.java. that corresponding thread will run incrementing the count.

Since the sleep () method throws an InterruptedException.3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14 :} public int count = 1. Since it inherits from a Thread. THE THREAD_EX CLASS THE CLASS AND INSTANCE VARIABLES 1: public class thread_ex extends java. } As you can see this class is very simple. } stop (). Line 6 says to keep running while the count is less than or equal to 50.applet. this exception must be caught whenever the sleep () method is applied. the only method that needs to be created is the run () method. Line 8 will cause the thread to sleep for the specified number of milliseconds. you will notice that the Counter class inherits from the Thread class.Applet implements Runnable { 2: /* APPLET */ 53 . public void run() { while (count < 50) { try { sleep(1000). The thread does not lose ownership of any monitors. Line 10 increments the count by one. Sleeping causes the currently executing thread to temporarily cease execution for the specified amount of time. line 12 calls the stop () method to stop the thread from running once it has reached 50. To catch the exception the try {} catch () {} clause should be used. Finally. } catch (InterruptedException e) { } count++. Line 7 is the form of exception handling used in Java. If you first look at Line 1.

setPriority (2). i++) { 54 . updateThread. clicked[i] = false. i< NUMCOUNTERS. Counter [] counters = new Counter [NUMCOUNTERS]. "Count Program"). but it also implements the Runnable interface. } /* Make on/off buttons for threads */ for (int i = 0. i++) { counters[i] = new Counter(). final static int SPACING = 23. while line 7 declares a Thread called the update Thread to be initially null. Line 4 handles the spacing between the two threads displayed. init() method 1: 2: 3: 4: 5: 6: 7: 8: 10: 11: 12: 13: 14: 15: public void init () { /* Make new counters */ for (int i = 0. i < NUMCOUNTERS. NUMCOUNTERS is the number of instances of the Counter class. } /* Make updateThread for drawing */ if (updateThread == null) { updateThread = new Thread (this.3: 4: 5: 7: 8: final static int NUMCOUNTERS = 2. boolean [] clicked = new boolean [NUMCOUNTERS]. Line 1 inherits from the Applet class like the previous examples.setPriority (NUMCOUNTERS+2). Thread update Thread = null. This interface is the interface that allows the user to use threads. The update Thread will be the thread used to handle the applet events. It is also declared to be unchangeable (a constant) by the modifier final. counters[i]. Line 3 declares an int called NUMCOUNTERS which is declared a class variable by the modifier static. Line 6 declares an array of counters.

} else if (clicked[i] == false) { // Button hit so resume 55 .start (). i < NUMCOUNTERS.isAlive()) updateThread.start (). i++) { if (bname.16: 17: 18: 19: } } add (new Button (("ON/OFF " + i))). check_button method 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: void check_button (String bname) { // Start updateThread if (!updateThread. If it has not. which is greater than the counters thread. then a new thread is created with the call in Line 11. and the second parameter is the name you want to associate with the thread. Line 10 checks to see if the updateThread has been created already. Line 5 sets the individual counters thread priority to 2. This greater priority means that the updateThread will be scheduled for execution before the counters threads. for (int i = 0.isAlive ()) { // Never started so start it counters[i]. The first parameter is the Runnable target. Line 12 sets the priority for the updateThread to NUMCOUNTERS+2 (in this case 4).equals("ON/OFF " + i)) { // Start that buttons thread if (!counters[i].

The start () method will call the run () method defined for that thread along with setting up some other information. i < NUMCOUNTERS. Line 13 runs the counters start () method if the counters thread is not alive.suspend (). If it has not.sleep(1000).17: 18: 19: 20: 21: 22: 23: 24: 25: 26: } } } } } counters[i].currentThread()) { // Repaint until count > 50 for (int i = 0.count <= 50) { repaint(). RUN () METHOD public void run () { while (updateThread == Thread. clicked[i] =!clicked[i]. Lines 19-22 will suspend the running counters thread. } catch (InterruptedException e) {} 56 . else if (clicked[i] == true) { // Button hit so turn off counters[i]. try { updateThread. i++) { if (counters[i]. Else if the button was clicked upon resume the suspended thread as stated in lines 15-18. // Say button was hit Line 4 uses the isAlive () method call to test if the updateThread has started.resume (). it is started by using the start () method.

} } } The run () method is the method invoked whenever the start () is applied to a thread.isAlive ()) { updateThread = null.stop(). } } if (updateThread. you most likely do not want the threads to still be running.count > 50) stop(). The stop () 57 . i++) { if (counters[i].isAlive ()) { Counters[i] = null. i< NUMCOUNTERS. } for (int i = 0. i++) { if (counters[i] != null) if (counters[i]. Then when both counters have reached 50 the threads are stopped. STOP () METHOD public void stop () { // Stops all threads for (int i = 0.} else counters[i]. It sleeps for every 1000 milliseconds to give the counters threads a chance to run. All the run () method does in this example is handle the repainting of the applet. If the user decides to hit the Back button on the browser. i < NUMCOUNTERS. } } This method simply will stop all the running threads.

Locks around shared variables allow Java threads to quickly and easily communicate and synchronize. as shown in the following code sample. The stop () method is invoked whenever the applet is scrolled out of view. or the page the applet is no longer being looked at. the sleeping thread moves to the ready-to-run queue. finishes its work. a thread can acquire the lock for an object by using the synchronized keyword. each object has a lock. int nCopies) { //only one thread executes this at a time } 58 . Methods. We achieve this by having methods (in the Copier object) that modify the copier state be declared as synchronized methods. or synchronized blocks of code. another thread cannot acquire the lock until the original thread wakes up. Workers that need to use a Copier object have to wait in line because only one thread per Copier object can be executing synchronized code. Locks Most applications require threads to communicate and synchronize their behavior to one another. The simplest way to accomplish this task in a Java program is with locks. Continuing with our copier analogy. can only be executed by one thread at a time for a given instantiation of a class. and releases the lock. In Java programming. Threads that attempt to acquire a lock in use go to sleep until the thread holding the lock releases it. Even if the thread with the lock is preempted. Imagine a lock on the copy machine for which only one worker can possess a key at a time. because that code requires obtaining the object's lock before execution. threads can acquire and release a lock before using resources. Without the key.method does this procedure by setting the threads to null if they are still alive. To prevent multiple accesses. class CopyMachine { public synchronized void makeCopies(Document d. A thread that holds a lock on an object knows that no other thread will access that object. allowing only one worker access at a time. to avoid clashing copiers. use of the machine is impossible. we can simply synchronize access to the copier resource. After the lock is freed.

Because every object has a lock. Why lock up an entire object. overwrite members.public void loadPaper() { //multiple threads could access this at once! synchronized(this) { //only one thread accesses this at a time //feel free to use shared resources. etc. we can use dummy objects as simple locks. Object xlock = new Object(). using a lock at the object level is too coarse. public void foo() { synchronized(xlock) { //access x here } //do something here .but don't use shared resources synchronized(ylock) { //access y here } } 59 . y. ylock = new Object(). } } } Fine-grain locks Often. as shown here: class FineGrainLock { MyMemberClass x. it's unnecessary to lock all threads out of the whole object in order to have one thread use only a subset of the thread's resources. disallowing access to any other synchronized method for only brief access to shared resources? If an object has multiple resources.

" This problem occurs when one thread is completing work that another thread will use. incrementing the counter. Threads that attempt to acquire a semaphore when all the resources managed by the semaphore are in use simply block until a resource is free. To use a 60 . A counting semaphore encapsulates managing the pool of available resources. These threads need to connect to a database. the semaphore is released. As each thread acquires the semaphore. Upon consumption of the resource. not the object-wide lock that a synchronized method acquires. For example. Semaphores Frequently. they are using the member locks. Implemented on top of simple locks.public void bar() { synchronized(xlock) { synchronized(ylock) { //access both x and y here } } //do something here . but only a fixed number of available database connections are available. several threads will need to access a smaller number of resources. The consuming thread can only obtain more data after the producing thread finishes generating it. How can you assign a number of database connections to a larger number of threads efficiently? One way to control access to a pool of resources (rather than just with a simple one-thread lock) is to use what is known as a counting semaphore. we would initialize a semaphore to the number of database connections available. imagine a number of threads running in a Web server answering client requests. A common use of semaphores is in solving the "consumer-producer problem. For example. the number of available connections is decremented by one.but don't use shared resources } } These methods need not be synchronized at the method level by declaring the whole method with the synchronized keyword. a semaphore is a thread-safe counter initialized to the number of resources available for use.

A simple implementation follows: class Semaphore { private int count.semaphore in this manner. For each unit of work completed. } public synchronized void release() { count++. This approach is more efficient than having a consuming thread wake up. } catch (InterruptedException e) { //keep trying } } count--. Each time a consumer consumes a unit of data and needs another. notify(). the producing thread signals (releases) the semaphore. it attempts to acquire the semaphore again. and sleep if nothing is available. they are easily implemented on top of object locks. you create a semaphore with the initial value of zero and have the consuming thread block on the semaphore. public Semaphore(int n) { this. check for completed work.count = n. } public synchronized void acquire() { while(count == 0) { try { wait(). //alert a thread that's blocking on this semaphore } } 61 . Though semaphores are not directly supported in the Java language. resulting in the value of the semaphore always being the number of units of completed work ready for consumption.

An example of such a violation is an attempt to index outside the bounds of an array. the Java programming language specifies that an exception will be thrown when semantic constraints are violated and will cause a non-local transfer of control from the point where the exception occurred to a point that can be specified by the programmer. Neither of these approaches is compatible with the design goals of the Java platform: to provide portability and robustness. using throw statements 62 . other programming languages allow an implementation to react in an arbitrary or unpredictable way. Programs can also throw exceptions explicitly. Instead. Some programming languages and their implementations react to such errors by peremptorily terminating the program. the Java virtual machine signals this error to the program as an exception. An exception is said to be thrown from the point where it occurred and is said to be caught at the point to which control is transferred.Chapter 5 EXCEPTION HANDLING MECHANISM Objectives    Understanding Exception Handling Pre-defined Exceptions User-defined Exceptions Exceptions When a program violates the semantic constraints of the Java programming language.

Every exception is represented by an instance of the class Throw able or one of its subclasses. The Causes of Exceptions An exception is thrown for one of three reasons:  An abnormal execution condition was synchronously detected by the Java virtual machine. A detailed example is then followed by an explanation of the exception hierarchy. method and constructor invocations. During the process of throwing an exception. This chapter describes the different causes of exceptions It details how exceptions are checked at compile time and processed at run time. This process continues until a handler is found that indicates that it handles that particular exception by naming the class of the exception or a super class of the class of the exception. leading to programs that are not robust. Experience shows that too often such funny values are ignored or not checked for by callers. so that locks are released as synchronized statements and invocations of synchronized methods complete abruptly. or both. Such conditions arise because: 63 . The exception mechanism of the Java platform is integrated with its synchronization model. and field initialization expressions that have begun but not completed execution in the current thread. initializes. one by one. such an object can be used to carry information from the point at which an exception occurs to the handler that catches it. statements. If no such handler is found. then the method uncaught Exception is invoked for the Thread Group that is the parent of the current thread-thus every effort is made to avoid letting an exception go unhandled. the Java virtual machine abruptly completes.Explicit use of throw statements provides an alternative to the old-fashioned style of handling error conditions by returning funny values. exhibit undesirable behavior. any expressions. such as the integer value -1 where a negative value would not normally be expected. Handlers are established by catch clauses of try statements.

collectively. All other exception classes are checked exception classes. the exception classes. The unchecked exceptions classes are the class Runtime Exception and its subclasses.2. such as an integer divide by zero. Additional exception classes. These classes are. §12. by analyzing which checked exceptions can result from execution of a method or constructor. such as using too much memory These exceptions are not thrown at an arbitrary point in the program.6 o o an error occurs in loading or linking part of the program (§12. but rather at a point where they are specified as a possible result of an expression evaluation or statement execution. the throws clause for the method or constructor must mention the class of that exception or one of the super classes of the class of that exception.3) some limitation on a resource is exceeded. An asynchronous exception occurred either because: o o the method stop of class Thread was invoked an internal error has occurred in the virtual machine Exceptions are represented by instances of the class Throwable and instances of its subclasses. may be declared by programmers. both checked and unchecked.   A throw statement was executed. as summarized in §15. For each checked exception which is a possible result. 64 . Compile-Time Checking of Exceptions A compiler for the Java programming language checks. for a description of the exception class hierarchy and some of the exception classes defined by the Java API and Java virtual machine. at compile time. both checked and unchecked. This compile-time checking for the presence of exception handlers is designed to reduce the number of exceptions which are not properly handled. The Java API defines a number of exception classes. that a program contains handlers for checked exceptions. and the class Error and its subclasses.o evaluation of an expression violates the normal semantics of the language.

more than one method declaration may be overridden by a single overriding declaration. In this case. having to declare such exceptions would not aid significantly in establishing the correctness of programs. even though this may be obvious to the programmer. are usually not sufficient to establish that such run-time exceptions cannot occur. The throws clause of an overriding method may not specify that this method will result in throwing any checked exception which the overridden method is not permitted. in the judgment of the designers of the Java programming language. Why Errors are not checked Those unchecked exception classes which are the error classes (Error and its subclasses) are exempted from compile-time checking because they can occur at many points in the program and recovery from them is difficult or impossible. The information available to a compiler. a compile-time error occurs. the programmer can then be certain that a Null 65 . if one does. must not result in a checked exception. certain code might implement a circular data structure that. can never involve null references. by construction. For example. pointlessly. A program declaring such exceptions would be cluttered. by its throws clause. the overriding declaration must have a throws clause that is compatible with all the overridden declarations. class variable initializes.The checked exception classes named in the throws clause are part of the contract between the implementor and user of the method or constructor. When interfaces are involved. and instance initializes or instance variable initializes within named classes and interfaces. Static initializes. and the level of analysis the compiler performs. to throw. Why Runtime Exceptions are not checked The runtime exception classes (Runtime Exception and its subclasses) are exempted from compile-time checking because. No such restriction applies to instance initializes or instance variable initializes within anonymous classes. Requiring such exception classes to be declared would simply be an irritation to programmers. Many of the operations and constructs of the Java programming language can result in runtime exceptions.

then the caller is the method invocation expression that was executed to cause the method to be invoked. The control transfer that occurs when an exception is thrown causes abrupt completion of expressions and statements until a catch clause is encountered that can handle the exception. control is transferred from the code that caused the exception to the nearest dynamically-enclosing catch clause of a try statement that handles the exception. 66 .  If within a constructor or an instance initialize or the initialize for an instance variable.PointerException cannot occur. execution then continues by executing the block of that catch clause. A statement or expression is dynamically enclosed by a catch clause if it appears within the try block of the try statement of which the catch clause is a part. or if the caller of the statement or expression is dynamically enclosed by the catch clause. Equivalently.  If within a static initializer or an initializer for a static variable. then the caller is the expression that used the class or interface so as to cause it to be initialized. The theorem-proving technology that is needed to establish such global properties of data structures is beyond the scope of this specification. Whether a particular catch clause handles an exception is determined by comparing the class of the object that was thrown to the declared type of the parameter of the catch clause. The code that caused the exception is never resumed. Handling of an Exception When an exception is thrown. The catch clause handles the exception if the type of its parameter is the class of the exception or a super class of the class of the exception. then the caller is the class instance creation expression or the method invocation of new Instance that was executed to cause an object to be created. The caller of a statement or expression depends on where it occurs:  If within a method. a catch clause will catch any exception object that is an instance of the declared parameter type. but it would be difficult for a compiler to prove it.

then the reason for the abrupt completion of the try block is discarded and the new reason for abrupt completion is propagated from there.If no catch clause handling an exception can be found. a try statement with a finally clause may be used. No expressions. and at a point in the program that is specified to possibly result in such an 67 . If a finally clause is executed because of abrupt completion of a try block and the finally clause itself completes abruptly. then the finally clause is executed during propagation of the exception. all effects of the statements executed and expressions evaluated before the point from which the exception is thrown must appear to have taken place. even if no matching catch clause is ultimately found. then the current thread (the thread that encountered the exception) is terminated. If optimized code has speculatively executed some of the expressions or statements which follow the point at which the exception occurs. such code must be prepared to hide this speculative execution from the user-visible state of the program. but only after all finally clauses have been executed and the method uncaught Exception has been invoked for the Thread Group that is the parent of the current thread. even if that other block of code completes abruptly. statements. In situations where it is desirable to ensure that one block of code is always executed after another. Handling Asynchronous Exceptions Most exceptions occur synchronously as a result of an action by the thread in which they occur. If a try or catch block in a try-finally or try-catch-finally statement completes abruptly. The exact rules for abrupt completion and for the catching of exceptions are specified in detail with the specification of each statement in and for expressions in Exceptions are Precise Exceptions are precise: when the transfer of control takes place. or parts thereof that occur after the point from which the exception is thrown may appear to have been evaluated.

Proper understanding of the semantics of asynchronous exceptions is necessary if highquality machine code is to be generated. the code generator has some flexibility to reorder computation between control transfers for greater performance. An asynchronous exception is.} 68 . They are asynchronous because they may occur at any point in the execution of the other thread or threads. an exception that can potentially occur at any point in the execution of a program. The Java platform permits a small but bounded amount of execution to occur before an asynchronous exception is thrown. Since a program has a finite size.exception. This delay is permitted to allow optimized code to detect and throw these exceptions at points where it is practical to handle them while obeying the semantics of the Java programming language. Since no asynchronous exception will occur between control transfers. An Internal Error is considered asynchronous. asynchronous exceptions are precise An Example of Exceptions Consider the following example: class TestException extends Exception { TestException () {super () . Asynchronous exceptions are rare. by contrast. A simple implementation might poll for asynchronous exceptions at the point of each control transfer instruction. They occur only as a result of:   An invocation of the stop methods of class Thread or Thread Group An internal error in the Java virtual machine The stop methods may be invoked by one thread to affect another thread or all the threads in a specified thread group.} TestException (String s) {super(s) . this provides a bound on the total delay in detecting an asynchronous exception. Like all exceptions.

} finally { System.length().out.getClass () + "\n } } } static int thrower (String s) throws TestException { try { if (s. return i/i. i < args. i++) { try { Thrower (args[i]).equals("test")) throw new TestException("Test message"). } if (s. 69 .println("[thrower(\"" + s + "\") done]").out.out.equals("null")) { s = null.equals("divide")) { int i = 0. } catch (Exception e) { System. with message:” + e.println ("Test \"" + args[i] + "\" didn't throw an exception"). return 0. } if (s. System.getMessage ()).println ("Test \"" + args[i] + "\" threw a " + e. return s.} class Test { public static void main (String[] args) { for (int i = 0.length.

lang. causing exceptions to be thrown three of the four times.ArithmeticException with message: / by zero [thrower ("null") done] Test "null" threw a class java. whether or not an exception occurs. passing it the arguments: divide null not test it produces the output: [thrower ("divide") done] Test "divide" threw a class java. 70 .lang. The try statement in method main catches each exception that the thrower throws. as shown by the "[thrower (. The main method of class Test invokes the thrower method four times.} } } If we execute the test program..NullPointerException with message: null [thrower ("not") done] Test "not" didn't throw an exception [thrower ("test") done] Test "test" threw a class TestException With message: Test message This example declares an exception class Test Exception. a message is printed describing what happened. Whether the invocation of thrower completes normally or abruptly.. The declaration of the method thrower must have a throws clause because it can throw instances of Test Exception.) done]" output that occurs for each invocation. Notice that the finally clause is executed on every invocation of thrower. A compile-time error would occur if the throws clause were omitted. which is a checked exception class.

or define additional exception classes. The class Runtime Exception is a direct subclass of Exception. The classes Exception and Error are direct subclasses of Throwable. linkage. as subclasses of Throwable or of any of its subclasses. as appropriate. The class Error and its subclasses are exceptions from which ordinary programs are not ordinarily expected to recover. verification or initialization error occurs. Programs can use the pre-existing exception classes in throw statements. The class Exception is the super class of all the exceptions that ordinary programs may wish to recover from. distinct from Exception in the class hierarchy. preparation. See the Java API specification for a detailed description of the exception hierarchy. a direct subclass of Object. The class Error is a separate subclass of Throwable. 71 .The Exception Hierarchy The possible exceptions in a program are organized in a hierarchy of classes. Loading and Linkage Errors The Java virtual machine throws an object that is an instance of a subclass of Linkage Error when a loading. to allow programs to use the idiom: } catch (Exception e) { To catch all exceptions from which recovery may be possible without catching errors from which recovery is typically not possible. The subclasses of Runtime Exception are unchecked exception classes. To take advantage of the Java platform's compile-time checking for exception handlers. The class Runtime Exception is a subclass of class Exception. rooted at class Throw able. it is typical to define most new exception classes as checked exception classes. The subclasses of Exception other than Runtime Exception are all checked exception classes. specifically as subclasses of Exception that are not subclasses of Runtime Exception.

User Defined Exceptions class BoringLectureException extends Exception { public BoringLectureException () { Super (). } } class NewExceptionTest { public static void dullSpeaker () throws BoringLectureException { // Code can go here throw new BoringLectureException (“Change Topics”).Virtual Machine Errors The Java virtual machine throws an object that is an instance of a subclass of the class Virtual Machine Error when an internal error or resource limitation prevents it from implementing the semantics of the Java programming language. 72 . } public BoringLectureException (String errorMessage) { super (error Message). See The Java Virtual Machine Specification Second Edition for the definitive discussion of these errors. } public static void main (String args []) { try { dullSpeaker ().

return.java -.0.} catch (BoringLectureException e) { System.out.java 1 // Pre.out. /* Correctly formated.out.getMessage() ).doubleValue ().println ("The argument must be a real number.try/catch statement and predefined exceptions 2 public class Pre 3{ 4 5 6 7 8 9 11 12 13 14 15 double d = Double. } } } Output Error: Time to Change Topics Try/Catch Statement and Predefined Exceptions The Java Program: Pre. Numbers that are very close to zero are set to ±0.println( "Error: Time to " + e."). return. */ System. 73 .println (d).err. } catch (ArrayIndexOutOfBoundsException e) { System. but extreme values are set to ±Infinite by "valueOf". public static void main (String argv[]) { try { 16 } catch (NumberFormatException e) { 17 18 System.").println ("An argument is required.valueOf (argv [0]).

io. in = null. } catch (NumberFormatException e) { e.err).FileNotFoundException. } catch (NullPointerException e) { e. FileInputStream in = new FileInputStream (args[n]).printStackTrace (System.valueOf(args[0]).err).err).io.printStackTrace (System.printStackTrace (System.19 20 21 } } } The Java Program: Trace. 5 Import java.IOException.java 2 3 Use "java -Djava.compiler=NONE Trace" to see line numbers in stack trace.intValue(). } catch (IOException e) { e.io. 7 public class Trace { 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 } } } public static void main (String args[]) { try { final int n = Integer.java 1 // Trace. in.err).printStackTrace (System. } catch (ArrayIndexOutOfBoundsException e) { e.FileInputStream.err). 6 import java.printStackTrace (System. 74 . } catch (FileNotFoundException e) { e.close (). 4 import java.

compiler=NONE Trace" to see line numbers in stack trace. throw e. 5 import java.printStackTrace (System.The Java Program: Reraise. } // Not reached } catch (ArrayIndexOutOfBoundsException e) { e.err). 4 import java. } catch (FileNotFoundException e) { e.java 2 3 Use "java -Djava. } catch (NumberFormatException e) { e. throw e.err).io.FileNotFoundException. 75 . case 1: throw new NumberFormatException ("merde!").printStackTrace (System. } catch (NoSuchElementException e) { e.printStackTrace (System.NoSuchElementException.err). NoSuchElementException.err).util. or FileNotFoundException public static void main (String argv[]) throws Exception { try { switch (0) { case 0: throw new ArrayIndexOutOfBoundsException ("darn!"). case 3: throw new FileNotFoundException ("mierda!"). case 2: throw new NoSuchElementException ("Scheiße!").printStackTrace (System.java 1 // Reraise. 6 public class Reraise { 7 8 9 10 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ArrayIndexOutOfBoundsException. throw e. NumberFormatException.

76 .30 31 32 33 } } } throw e.

JDBC is commonly used to connect a user program to a "behind the scenes" database. regardless of what database management software is used to control the database. 77 . which is available for free download from Sun's site.Chapter 6 JDBC . spreadsheets. This article will provide an introduction and sample code that demonstrates database access from Java programs that use the classes of the JDBC API. In this way. JDBC is cross-platform.JAVA DATABASE CONNECTIVITY Objectives       Understanding JDBC Know about Connectivity Drivers Connecting to Database Structuring Statements Storing data to Database Retrieving data from Database What is JDBC? Java Database Connectivity (JDBC) is a programming framework for Java developers writing programs that access information stored in databases. and flat files.

JDBC drivers use Java's built-in Driver Manager to open and access a database from within your Java program. JDBC makes connecting to a data source less difficult by providing a collection of classes that abstract details of the database interaction. ODBC consolidated much of the commonality between database management systems. or driver (Oracle. Microsoft. 78 . including products produced by Microsoft and Oracle.A database that another program links to is called a data source. Software engineering with JDBC is also conducive to module reuse. retrieving records. Programs can easily be ported to a different infrastructure for which you have data stored (whatever platform you choose to use in the future) with only a driver substitution. JDBC-ODBC bridges have been created to allow Java programs to connect to ODBC-enabled database software This article assumes that readers already have a data source established and are moderately familiar with the Structured Query Language (SQL). and increases the level of abstraction. MySQL. already use a standard called Open Database Connectivity (ODBC). You can download a specific JDBC driver from the manufacturer of your database management system (DBMS) or from a third party (in the case of less popular open source products). See Hoffman's tutorial on SQL if you are a beginner or need some refreshing Using a JDBC driver Regardless of data source location. which your program is going to run. platform. a command to the Driver Manager.). the command language for adding records. Many legacy C and Perl programs use ODBC to connect to data sources. etc. This essentially requires only one line of code. Informix.The JDBC driver for your database will come with specific instructions to make the class files of the driver available to the Java Virtual Machine. As long as you stick with the more popular database platforms (Oracle. Many data sources. and other basic database manipulations.). there is almost certainly a JDBC driver written to let your programs connect and manipulate data. etc. To begin connecting to a data source. JDBC builds on this feature. you first need to instantiate an object of your JDBC driver. Microsoft.

vusports. The String parameter below is the fully qualified class name of the driver you are using for your platform combination: Connecting to your database To actually manipulate your database. Our example JDBC driver uses an object of the Properties class to pass information through the Driver Manager. which usually involves standard password authentication for a database account. where permissions should have been established to govern access privileges. which yields a Connection object: 79 . where its methods will be available to your program. It will look similar to our example. The account name and password you give the driver should have meaning within your DBMS. machine host name and optional port number. The standard least common denominator for authentication to a database is a pair of strings. Your JDBC driver will come with instructions detailing how to form the URL for your database. At the very least.telling the Java Virtual Machine to load the byte code of your driver into memory.html The URL for our example driver and database looks like this: jdbc: mysql: //db_server:3306/contacts/ Even though these two URLs look different. the Uniform Resource Locator (URL) standard is good for much more than telling your browser where to find a web page: http://www. As you may already be aware. You will want to control access to your data.com/index. an account and a password. and the relative path of the resource. your driver will need a URL for the database and parameters for access control. unless security is not an issue. you need to get an object of the Connection class from your driver. they are actually the same in form: the protocol for connection.

"contacts"). Naturally. Connection con = DriverManager. We write commands to be executed by the DBMS on a database using SQL. For example: INSERT INTO songs VALUES ( "Jesus Jones". consult your reference material. The syntax of a SQL statement. we can easily pass commands through it to the database. INSERT INTO songs VALUES ( "Def Leppard". which in turn are composed of rows. the order of the values being inserted into the table must match the order of the corresponding columns of the table.setProperty ("user". usually consists of an action keyword. Now that we have a Connection object. taking advantage of the abstraction layers provided by JDBC. props). These SQL queries each added a row of data to table "songs" in the database. or query. "Hysteria").Properties props = new Properties (). "Right Here. 80 . Each database table has a set of rows that define what data types are in each record. Structuring statements Databases are composed of tables. For more information about the supported data types in your DBMS. and the data types of the new values must match the data types of the corresponding columns.getConnection ( "jdbc: mysql: //localhost:3306/contacts/". Right Now"). "blackbook"). and some parameters. props. a target table name. props. Records are also stored as rows of the database table with one row per record.setProperty ("password". We use the data source connection created in the last section to execute a command to the database.

Rather than type all the data from the flat file into the DBMS. TABLE_NAME = "records". we examine a very simple text file. HOST = "jdbc:mysql://db_lhost:3306/". inserting each row into a database table.sql. you may want to create a program that reads in the text file. Execute a SQL statement to insert the record. Loop until the end of the file: o o o Read a line of text from the flat file.*. public class TextToDatabaseTable { private static final String DB = "contacts". import java. String query = . Statement stmt = con.To execute an SQL statement using a Connection object.executeQuery (query). There are only a few rows and columns. // define query stmt. 81 . but the principle here can be applied and scaled to larger problems.. In this case. which has been created to model the original flat file structure.io. Example: Parsing a text file into a database table In the course of modernizing a record keeping system.*. Parse the line of text into the columns of the table. Here is the code of the example program: import java. which will execute the query contained in a String.*.. There are only a few steps:   Open a connection to the database. you encounter a flat file of data that was created long before the rise of the modern relational database. you first need to create a Statement object. import java.util.createStatement ().

ACCOUNT = "account", PASSWORD = "nevermind", DRIVER = "org.gjt.mm.mysql.Driver", FILENAME = "records.txt";

public static void main (String [] args) { try {

// connect to db Properties props = new Properties (); props.setProperty ("user", ACCOUNT); props.setProperty ("password", PASSWORD);

Class.forName (DRIVER).newInstance (); Connection con = DriverManager.getConnection ( HOST + DB, props); Statement stmt = con.createStatement ();

// open text file Buffered Reader in = new Buffered Reader ( new FileReader(FILENAME));

// read and parse a line String line = in.readLine (); while (line != null) {

StringTokenizer tk = new StringTokenizer (line); String first = tk.nextToken (), last = tk.nextToken (), email = tk.nextToken (), phone = tk.nextToken ();

82

// execute SQL insert statement String query = "INSERT INTO " + TABLE_NAME; query += " VALUES (" + quote (first) + ", "; query += quote (last) + ", "; query += quote (email) + ", "; query += quote (phone) + ");"; stmt.executeQuery (query);

// prepare to process next line line = in.readLine (); } in. close (); }

catch (Exception e) { e.printStackTrace (); } }

// protect data with quotes private static String quote (String include) { return ("\"" + include + "\""); } } Processing a result set Perhaps even more often than inserting data, you will want to retrieve existing information from your database and use it in your Java program. The usual way to implement this is with another type of SQL query, which selects a set of rows and columns from your

83

database and appears very much like a table. The rows and columns of your result set will be a subset of the tables you queried, where certain fields match your parameters. For example: SELECT title FROM songs WHERE artist="Def Leppard"; This query returns: title Hysteria The boxed portion above is a sample result set from a particular database program. In a Java program, this SQL statement can be executed in the same way as in the insert example, but additionally, we must capture the results in a Result Set object. Statement stmt = concrete Statement (); String query = "SELECT FROM junk;” // define query Result Set answers = stmt.executeQuery (query); The JDBC version of a query result set has a cursor that initially points to the row just before the first row. To advance the cursor, use the next () method. If you know the names of the columns from your result set, you can refer to them by name. You can also refer to the columns by number, starting with 1. Usually you will want to get access all of the rows of your result set, using a loop as in the following code segment: while (answers.next ()) { String name = answers.getString("name"); int number = answers.getInt ("number"); // do something interesting } All database tables have Meta data that describe the names and data types of each column; result sets are the same way. You can use the Result Set Meta Data class to get the column count and the names of the columns, like so: Result Set Meta Data meta = answers.getMetaData ();
84

String [] colNames = new String [meta.getColumnCount ()]; for (int col = 0; col < colNames.length; col++) colNames [col] = meta.getColumnName (col + 1); Example: Printing a database table We choose to write a simple software tool to show the rows and columns of a database table. In this case, we are going to query a database table for all its records, and display the result set to the command line. We could also have created a graphical front end made of Java Swing components. Notice that we do not know anything except the URL and authentication information to the database table we are going to display. Everything else is determined from the ResultSet and its meta data. Comments in the code explain the actions of the program. Here is the code of the example program: import java.sql.*; import java.util.*;

public class DatabaseTableViewer { private static final String DB = "contacts", TABLE_NAME = "records", HOST = "jdbc:mysql://db_host:3306/", ACCOUNT = "account", PASSWORD = "nevermind", DRIVER = "org.gjt.mm.mysql.Driver";

public static void main (String [] args) { try {

// authentication properties
85

} // hold data from result set while (table.".setProperty ("password".next ()) { for (int col = 0. props). col < colNames. ResultSet table = stmt.getMetaData (). } } 86 .getColumnName (col + 1).forName (DRIVER).getObject (colNames [col]). props. cells [col] = new Vector ().newInstance (). col++) { Object cell = table. col++) { colNames [col] = meta. props. PASSWORD).length.length. col < colNames. Statement stmt = con. // load driver and prepare to access Class.getConnection ( HOST + DB. // determine properties of table ResultSetMetaData meta = table.createStatement ().getColumnCount ()].Properties props = new Properties (). String [] colNames = new String [meta. for (int col = 0. ACCOUNT). // execute select query String query = "SELECT * FROM " + TABLE_NAME + ". cells [col]. Vector [] cells = new Vector [colNames.length]. Connection con = DriverManager.executeQuery (query).setProperty ("user".add (cell).

out.toUpperCase () + "\t").printStackTrace (). // print data row-wise while (!cells [0].length.toString () + "\t").out.out.remove (0). } } // exit more gently catch (Exception e) { e.println ().// print column headings for (int col = 0.length.println (). col++) System. } } } 87 . col < colNames.print (cells [col]. System. System.print (colNames [col]. col++) System. col < colNames.out.isEmpty ()) { for (int col = 0.