Basic Java
Basic Java
Basic Java
Basic Java
Basic Java
1.
1. 2. 3. 4. 5. 6. 7. 8.
Table of Contents Introduction to Java ...3 The language package ................29 The Utilities package .................36 The I/O Package .48 Applet Programming ...............68 Multithreading .109 Networking in Java ..120 Java Database Connectivity 131
Basic Java
Java was designed to be a powerful language but simple. To support the development of large software, the concept of package is used. The major difference was the removal of the direct use of pointers. Java automatically handles referencing and dereferencing of language objects. Other difference includes the removal of support for data structures like struct, union. Its in-built classes provide this. Also, the concepts of operator overloading and multiple-inheritance in the form of classes have been removed.
OBJECT-ORIENTED NATURE
The notion of object in Java is implemented by its class construct. In fact, it is not possible to write a Java program that does something meaningful without using the class construct. Java language comes with very powerful set of pre-defined classes with a hierarchy level.
DISTRIBUTED NATURE
Java provides the network capabilities by a pre-defined package java.net. This package has many classes that simplify the network communication. Accessing to any remote object is also possible in Java via the java.rmi package.
ARCHITECTURALLY NEUTRAL
The Java Compiler does not produce the machine language instructions that make up the executable Java Program. The Java Compiler DOES NOT generate a .exe file. Instead the compiler produces an intermediate code called as 'byte code'. Java byte code is an architecturally neutral representation of the program, that is, it is independent of any processor type or machine architecture. These byte codes are read by the Java interpreter and the same is executed using an internal model of an abstract machine. The Java Interpreter and the implementation of this abstract machine are called the JAVA VIRTUAL MACHINE.
SECURE LANGUAGE
Before any Java program is interpreted, the Java runtime system performs a byte-code verification to ensure that the program is not violating the system integrity. Also,
Basic Java
3.
programs loaded from the net are loaded in a separate name space than the local classes. This prevents any other program to affect the system classes.
MULTITHREADED LANGUAGE
Java supports multitasking in the form of multithreading within itself. First Java Application
HelloWorld Application
public class HelloWorld { public static void main(String args[]) { System.out.println("Hello World!!"); } }
Create the file
Save this into a file called HelloWorld.java using any text editor. It is very important to call the file HelloWorld.java, because the compiler expects the file name to match the class identifier.
Compile the code
Type Prompt> javac HelloWorld.java at a command prompt. The javac program creates a file called HelloWorld.class from the HelloWorld.java file. Inside this file (HelloWorld.class) is text known as bytecodes which can be run by the Java interpreter.
Run the program
Now that you have compiled the program, you can run it by typing at the command prompt:
Promtpt> java HelloWorld
The input to the interpreter is nothing but the name of the class that has the main method. After you do this, the computer should print to the screen
Hello World!! Understanding HelloWorld Declaring a class
The first task when creating any Java program is to create a class. Look at the first line of the HelloWorld application:
Basic Java
4.
public class HelloWorld { This declares a class called HelloWorld. To create any class, simply write a line that looks like: public class ClassName Here, ClassName is the name of the program you are writing. In addition, ClassName must correspond to the file name. Next, notice the little curly brace ({) that is located after the class declaration. If you look at the end of the class, there is also a closing brace (}). The braces tell the compiler where your class will begin and end. Any code between those two braces is considered to be in the HelloWorld class. public static void main(String args[]){ This line declares what is known as the main method. Methods are essentially mini-programs. Each method performs some of the tasks of a complete program. The main method is the most important one with respect to applications, because it is the place that all Java applications start. For instance, when you run java HelloWorld, the Java interpreter starts at the first line of the main method.
Writing to the Screen
The text Hello World!! appears on the screen through System.out.println("Hello World!!"); You can replace any of the text within the quotation marks ("") with any text that you would like. The System.out line is run because, when the application starts up, the interpreter looks at the first line of code (namely the printout) and executes it. If you place any other code there, it runs that code instead. The System.out.println serves approximately the same purpose as the writeln in Pascal. In C, the function is printf, and in C++, cout.
println Versus print
There is one minor variation on println which is also readily used: print("Hello World!!"). The difference between println and print is that print does not add a carriage return at the end of the line, so any subsequent printouts are on the same line. Access Specifiers : The first option for a method is the access specifier. Access specifiers are used to restrict access to the method. Regardless of what the access specifier is, though, the method is accessible from any other method in the same class.
public
The public modifier is the most relaxed modifier possible for a method. By specifying a method as public it becomes accessible to all classes regardless of their lineage or their package. In other words, a public method is not restricted in any way.
5.
The second possible access modifier is protected. Protected methods can be accessed by any class within the current package, but are inaccessible to any class outside the package.
default
The next access modifier that can be applied to a class is that of default. Default methods are accessible only to the current class and any classes that extend from it. If you fail to specify an access modifier, the method is considered default.
private
private is the highest degree of protection that can be applied to a method. A private method is only accessible by those methods in the same class. Even classes that extend from the current class do not have access to a private class. Method Modifiers Method modifiers enable you to set properties for the method, such as where it will be visible and how subclasses of the current class will interact with it.
static
Placing the static modifier in front of a method or variable declaration makes it common to all object references of that class. While non-static methods can also operate with static variables, static methods can only deal with static variables and static methods.
abstract
Abstract methods are simply methods that are declared, but are not implemented in the current class. The responsibility of defining the body of the method is left to subclasses of the current class.
final
By placing the keyword final in front of the method declaration, you prevent any subclasses of the current class from overriding the given method. This ability enhances the degree of insulation of your classes, you can ensure that the functionality defined in this method will never be altered in any way. Note: Neither static methods nor class constructors can be declared to be abstract. Furthermore, you should not make abstract methods final, because doing so prevents you from overriding the method.
native
Native methods are methods that you want to use, but do not want to write in Java. Native methods are most commonly written in C++, and can provide several benefits such as faster execution time. Like abstract methods, they are declared simply by placing the modifier native in front of the method declaration and by substituting a semicolon for the method body.
synchronized
By placing the keyword synchronized in front of a method declaration, you can prevent data corruption that may result when two methods attempt to access the same piece of data at the same time. While this may not be a concern for simple
Basic Java
6.
programs, once you begin to use threads in your programs, this may become a serious problem.
Modified HelloWorld
In the above HelloWorld program, the print method was called inside the same class. The following example creates a separate PrintWorld object that has a print method and any other class can invoke this method to print the necessary result. class PrintWorld { String data_member; public PrintWorld(String line) { data_member = new String(line); } public void printMe() { System.out.println(data_member); } } public class ObjectWorld { public static void main(String args[]) { PrintWorld p_world = new PrintWorld("Hello World"); p_world.printMe(); } } In the above program, PrintWorld p_world = new PrintWorld("Hello World"); is used to construct the class PrintWorld. Quite simply, the line tells the compiler to allocate memory for an instance of the class and points variable to the new section of memory. In the process of doing this, the compiler also calls the class's constructor method and passes the appropriate parameters to it p_world is the object to the class PrintWorld. This class has a data member, data_member and a method printMe(). In the construction phase of the class, the argument of the constructor is assigned to the data member. And later when the printMe() method is called, this data member value is retrieved and printed.
Getting information from the user with System.in
System.out has a convenient partner called System.in. While System.out is used to print information to the screen, System.in is used to get information into the program.
Requesting input from the user
public class ReadHello { public static void main (String args[] { int inChar =0; System.out.println("Enter a Character:"); try { inChar = System.in.read(); System.out.println("You entered " + inChar); } catch (IOException e) { System.out.println("Error reading from user"); } } } You've probably already noticed that there is a lot more to this code than there was to the last one. Lets first compile the program. Enter a Character: A You entered 65 The code we are most interested in is the line, which reads: inChar = System.in.read(); System.in.read() is a method that takes a look at the character that the user enters. It then performs what is known as a return on the value. A value that is returned by a method is then able to be used in an expression. In the case of ReadHello, a variable called inChar is set to the value which is returned by the System.in.read() method. In the next line, the value of the inChar variable is added to the System.out string. By adding the variable into the string, you can see the results of your work. It's not actually necessary to use a variable. If you prefer, you can print it out directly in the second System.out line, by changing it to System.out.println("You entered "+ System.in.read()); Now, notice that the program displays a number instead of a character for what you entered. This is because the read() method of System.in returns an integer, not an actual character. The number corresponds to what is known as the ASCII character set. Converting integer to character To convert the number that is returned from System.in into a character, you need to do what is known as a cast. Casting effectively converts a given data type to another one.
Basic Java
8.
--inChar =(char) System.in.read(); --Notice the characters before System.in.read().The (char) causes the integer to be changed into a character.
The Rest of the Extra Codetry, catch
In this code, there is a sequence there called a try-catch block. In some programming languages, when a problem occurs during execution, there is no way for you as a programmer to catch it and deal with the problem. In some languages, it's a bit complicated. In Java, most problems cause what are known as Exceptions. When a method states that it will throw an exception, it is your responsibility to only try to perform that method, and if it throws the exception, you need to catch it. See the line of code right after the catch phase. If there is an error while reading, an exception called an IOException is thrown. When that happens, the code in the catch block is called. JAVA LANGUAGE FUNDAMENTALS
KEYWORDS
The following is a list of the 56 keywords you can use in Java. abstract boolean Break Byte case cast Catch Char class const Continue Default do double Else Extends final finally Float for future generic Goto if implements import Inner instanceof int interface Long native new null Operator outer package private Protected public rest return Short static super switch Synchronized this throw throws Transient try var void Volatile while
EXTENDING OBJECTS THROUGH INHERITANCE Inheritance is a feature of OOP programming that enables us inherit all the common features of a parent class onto a child class, it's not necessary to reinvent the object every time. When new classes inherit the properties of another class, they are referred to as child classes or subclasses. The class from which they are derived is then called a parent or super class.
A Simple Inheritance Program
Basic Java
9.
{ System.out.println("Base Class Constructor Called"); } } /* DerivedClass extends or inherits the property of the BaseClass */ class DerivedClass extends BaseClass { public DerivedClass() { System.out.println("Derived Class Constructed"); } } public class Inheritance { public static void main(String args[]) { BaseClass base = new BaseClass(); System.out.println("------------"); DerivedClass derived = new DerivedClass(); } } The output is: Base Class Constructor Called -----------Base Class Constructor Called Derived class Constructed By looking at the output, you can find that, when the child class is constructed, the parent class constructor is invoked first. INTERFACES Interfaces are Java's substitute for C++'s feature of multiple inheritance, the practice of allowing a class to have several super classes. While it is often desirable to have a class inherit several sets of properties, for several reasons the creators of Java decided not to allow multiple inheritance. Java classes, however, can implement several interfaces, thereby enabling you to create classes that build upon other objects without the problems created by multiple inheritance. The syntax for creating an interface is extremely similar to that for creating a class. However, there are a few exceptions. The most significant difference is that none of the methods in your
interface may have a body. An Interface Example
Basic Java
10 .
} public class Shoe implements Product { public int getPrice(int id) { if (id == 1) return(5); else return(10); } } public class Store { public static void main(String argv[]) { Shoe some = new Shoe(); int x = Some.getPrice(3); System.out.println(the price : +x); } }
The Declaration
Interface declarations have the syntax public interface NameofInterface Public Interfaces By default, interfaces may be implemented by all classes in the same package. But if you make your interface public, you allow classes and objects outside of the given package to implement it as well. The rules for an interface name are identical to those for classes.
Extending Other Interfaces
In keeping with the OOP practice of inheritance, Java interfaces may also extend other interfaces as a means of building larger interfaces upon previously developed code. e.g public interface NameOfInterface extends AnotherInterface Interfaces cannot extend classes. There are a number of reasons for this, but probably the easiest to understand is that any class, which the interface would be extending would have its method bodies defined. This violates the "prime directive" of interfaces.
The Interface Body
Basic Java
11 .
The main purposes of interfaces are to declare abstract methods that will be defined in other classes. As a result, if you are dealing with a class that implements an interface, you can be assured that these methods will be defined in the class. While this process is not overly complicated, there is one important difference that should be noticed. An interface method consists of only a declaration.
Methods in Interface
Method declarations in interfaces have the following syntax: public return_value nameofmethod (parameters); Note that unlike normal method declarations in classes, declarations in interfaces are immediately followed by a semicolon. All methods in interfaces are public by default, regardless of the presence or absence of the public modifier. This is in contrast to class methods which default to friendly. It's actually illegal to use any of the other standard method modifiers (including native, static, synchronized, final, private, protected, or private protected) when declaring a method in an interface.
Variables in Interfaces
Although interfaces are generally employed to provide abstract implementation of methods, you may also define variables within them. Because you cannot place any code within the bodies of the methods, all variables declared in an interface must be global to the class. Furthermore, regardless of the modifiers used when declaring the field, all fields declared in an interface are always public, final, and static. While all fields will be created as public, final, and static, you do not need to explicitly state this in the field declaration. All fields default to public, static and final regardless of the presence of these modifiers. It is, however, a good practice to explicitly define all fields in interfaces as public, final, and static to remind yourself (and other programmers) of this fact.
Implementing an interface.
In order to fulfill the requirements of implementing the Product interface, the class must override the getPrice(int) method.
Overriding Methods
Declaring a method in an interface is a good practice. However, the method cannot be used until a class implements the interface and overrides the given method.
ENCAPSULATION
Another benefit of enclosing data and methods in classes is the OOP characteristic of encapsulationthe ability to isolate and insulate information effectively from the rest of your program.
POLYMORPHISM
Basic Java
12 .
Finally, the allure of the OOP approach to creating self-sustaining modules is further enhanced by the fact that children of a given class are still considered to be of the same "type" as the parent. This feature, called polymorphism, enables you to perform the same operation on different types of classes as long as they share a common trait. While the behavior of each class might be different, you know that the class will be able to perform the same operation as its parent because it is of the same family tree
Example of Function Overload
class Sample { public Sample() { System.out.println("Sample Constructor Called"); } public void overloadMe() { System.out.println("Overload Method Invoked"); } public void overloadMe(String str) { System.out.println(str); } } public class Overload { public static void main(String args[]) { Sample samp = new Sample(); System.out.println("-------------"); samp.overloadMe(); System.out.println("-------------"); samp.overloadMe("Hi! I am not the old one"); } }
Output:
Sample Constructor Called ------------Overload Method Invoked ------------Hi! I am not the old one Here, though the method overloadMe is the same, it throws different ouput based on its invocation. This is termed as method overloading.
JAVA DATA TYPES
Java has Two Types of Data Types In Java, there are really two different categories in which data types have been divided:
Primitive types Reference types
Reference types enclose things such as arrays, classes, and interfaces. Java has eight primitive types, each with its own purpose and use:
Basic Java
13 .
Type Description boolean - These have values of either true or false. byte - 8-bit 2s-compliment integer with values between -128 to 127 short - 16-bit 2s-compliment integer with values between -2^15 and 2^15-1 (-32,768 to 32,767) char 16-bit Unicode characters. For alpha-numerics, these are the same as ASCII with the high byte set to 0. The numerical values are unsigned 16-bit values are between 0 and 65535. int 32-bit 2s-compliment integer with values between -231 and 231-1 (-2,147,483,648 to 2,147,483,647) long 64-bit 2s-compliment integer with values between -263 and 263-1 (9223372036854775808 to 9223372036854775807) float 32-bit single precision floating point numbers using the IEEE 754-1985 standard (+/about 1039) double 64-bit double precision floating point numbers using the IEEE 754-1985 standard. (+/- about 10317)
VARIABLES
You can create any variable in Java in the same way as was just shown: State the data type that you will be using State the name the variable will be called Assign the variable a value As with every other line of code in Java, terminate the line with a semicolon example: int number = 0; boolean value = false;
IdentifiersThe Naming of a Variable
There are several rules that must be obeyed when creating an identifier: The first character of an identifier must be a letter. After that, all subsequent characters can be letters or numerals. The underscore (_) and the dollar sign ($) may be used as any character in an identifier, including the first one. Identifiers are case-sensitive and language-sensitive.
Examples of Legal Identifiers
HelloWorld
Basic Java
14 .
Operators are used to change the value of a particular object. They are described here in several related categories.
UNARY LOGICAL OPERATORS Description Operator
++ --
Bitwise complement ~
Example for Increment and Decrement Operators
class IncDec { public static void main int x = 8, y = 13; System.out.println(x = System.out.println(y = System.out.println(++x System.out.println(y++ System.out.println(x = System.out.println(y = } } Output x=8 y = 13 ++x = 9 y++ = 13 x=9 y = 14
Example for negation operator
class Negation { public static void main (String args[]) { int x = 8; System.out.println(x = + x); int y = -x; System.out.println(y = + y);
Basic Java
15 .
} }
class BitwiseComplement public static void main int x = 8; System.out.println(x = int y = ~x; System.out.println(y = } }
ARITHMETIC OPERATORS
Addition Subtraction Multiplication Division Modulus Bitwise AND Bitwise OR Bitwise XOR Left Shift Right Shift
The left-shift, right-shift, and zero-fill-right-shift operators (<<, >>, and >>>) shift the individual bits of an integer by a specified integer amount. The following are some examples of how these operators are used: x << 3; y >> 7; z >>> 2;
Example for Shift Operators
class Shift { public static void main (String args[]) { int x = 7; System.out.println(x = + x); System.out.println(x >> 2 = + (x >> 2)); System.out.println(x << 1 = + (x << 1)); System.out.println(x >>> 1 = + (x >>> 1)); } } The output of Shift follows: x=7 x >> 2 = 1 x << 1 = 14
Basic Java
17 .
x >>> 1 = 3
Relational Operators
The last group of integer operators is the relational operators, which all operate on integers but return a type boolean.
Description Operator
Less Than Greater Than Less Than Or Equal To Equal To Not Equal To
ASSIGNMENT OPERATORS
The simplest assignment operator is the standard assignment operator. This operator is often known as the gets operator, because the value on the left gets the value on the right. = assignment operator The arithmetic assignment operators provide a shortcut for assigning a value. When the previous value of a variable is a factor in determining the value that you want to assign, the arithmetic assignment operators are often more efficient:
Description Operator
= += -= /= %= &= |= ^=
Multiplication *=
BOOLEAN OPERATORS
Boolean operators act on Boolean types and return a Boolean result. The Boolean operators are listed
Description Operator
& | ^ &&
Basic Java
18 .
! == ?:
Not Equal To !=
CONDITIONAL OPERATOR
It takes the following form: expression1 ? expression2 : expression3 In this syntax, expression1 must produce a Boolean value. If this value is true, then expression2 is evaluated, and its result is the value of the conditional. If expression1 is false, then expression3 is evaluated, and its result is the value of the conditional.
Example for Conditional Operator
class Conditional { public static void main (String args[]) { int x = 0; boolean isEven = false; System.out.println(x = + x); x = isEven ? 4 : 7; System.out.println(x = + x); } } The results of the Conditional program follow: x=0 x=7
CONTROL FLOW
Control flow is the heart of any program. Control flow is the ability to adjust (control) the way that a program progresses (flows). By adjusting the direction that a computer takes, the programs that you build become dynamic. Without control flow, programs would not be able to do anything more than several sequential operations.
IF STATEMENTS
Programmers use iteration statements to control sequences of statements that are repeated according to runtime conditions.
Basic Java
19 .
Java supports five types of iteration statements: while do for continue break
WHILE STATEMENTS
switch (expression){ case V1: statement1; break; case V2: statement2; break; default: statementD; }
BREAK STATEMENTS
The sub-statement blocks of loops and switch statements can be broken out of by using the break statement.
RETURN STATEMENTS
A return statement passes control to the caller of the method, constructor, or static initializer containing the return statement. If the return statement is in a method that is not declared void, it may have a parameter of the same type as the method.
ARRAYS
An array is simply a way to have several items in a row. If you have data that can be easily indexed, arrays are the perfect means to represent them.
Basic Java
20 .
int IQ[] = {123,109,156,142,131}; The next line shows an example of accessing the IQ of the third individual: int ThirdPerson = IQ[3]; Arrays in Java are somewhat tricky. This is mostly because, unlike most other languages, there are really three steps to filling out an array, rather than one: There are two ways to do this: place a pair of brackets after the variable type, or place brackets after the identifier name. int MyIntArray[]; int[] MyIntArray;
Examples of declaring arrays.
long Primes[] = new long[1000000]; // declare an array and assign // some memory to hold it. long[] EvenPrimes = new long[1]; // Either way, it's an array. EvenPrimes[0] = 2; // populate the array. There are several additional points about arrays you need to know: Indexing of arrays starts with 0. In other words, the first element of an array is MyArray[0], not MyArray[1].
COMMENTS
A traditional comment is a C-style comment that begins with a slash-star (/*) and ends with a star-slash (*/).
C++ Style Comments
The second style of comment begins with a slash-slash (//) and ends when the current source code line ends. These comments are especially useful for describing the intended meaning of the current line of code.
javadoc Comments
The final style of comment in Java is a special case of the first. It has the properties mentioned previously, but the contents of the comment may be used in automatically generated documentation by the javadoc tool. javadoc comments are opened with /**, and they are closed with */. By using these comments in an appropriate manner, you will be able to use JavaDoc to automatically create documentation pages
21 .
There are several different types of literal. In fact, there are five major types of literal, in the Java language: Boolean Character Floating-point Integer String Integer Literal
Example
int j=0; long GrainOfSandOnTheBeachNum=1L; short Mask1=0x007f; String FirstName = "Ernest"; char TibetanNine = '\u1049' boolean UniverseWillExpandForever = true;
ESCAPE CHARACTERS
Escape Literal Meaning '\b' \u0008 backspace '\t' \u0009 horizontal tab '\n' \u000a linefeed '\f' \u000c form feed '\r' \u000d carriage return '\"' \u0022 double quote '\'' \u0027 single quote '\\' \u005c backslash Don't use the \u format to express an end-of-line character. Use the \n or \r characters instead.
ERROR-HANDLING CLASSES
Runtime error handling is a very important facility in any programming environment. Java provides the following classes for dealing with runtime errors: Throwable Exception Error The Throwable class provides low-level error-handling capabilities such as an execution stack list. The Exception class is derived from Throwable and provides the base level of functionality for all the exception classes defined in the Java system. The Exception class is used for handling normal errors. The Error class is also derived from Throwable, but it is used for handling abnormal errors that arent expected to occur. Very few Java programs worry with the Error class; most use the Exception class to handle runtime errors.
public class ExceptionHandling { public static void main(String args[]) { int values[] = {5,6,3,5,2}; int index = 6; try { int get = values[index]; System.out.println("The value in the requested index is " +get); } catch(Exception err) { System.out.println("Requested Index Not found"); } finally { System.out.println("--------End---------"); } } } In the above example, the array size is 5, but we are trying to access the 6 element. As this is a runtime error, an exception is caught and the catch block is executed.
Use of finally clause
th
Suppose there is some action that you absolutely must do, no matter what happens. Usually, this is to free some external resource after acquiring it, to close a file after opening it, or something similar. In exception handling, the finally block is executed no matter whether an exception is thrown or not. Output: Requested Index Not found --------End--------THE THROWABLE CLASS
The Throwable class is the superclass of all errors and exceptions in the Java language. Only objects that are instances of this class (or of one of its subclasses) are thrown by the Java Virtual Machine or can be thrown by the Java throw statement. Similarly, only this class or one of its subclasses can be the argument type in a catch clause. A Throwable class contains a snapshot of the execution stack of its thread at the time it was created. It can also contain a message string that gives more information about the error.
THE EXCEPTION CLASS
The class Exception and its subclasses are a form of Throwable that indicates conditions that a reasonable application might want to catch.
EXAMPLE FOR MULTIPLE EXCEPTION HANDLING
Basic Java
23 .
int values[] = {5,6,2,3,5}; int index; char input = (char)-1; String data = ""; System.out.println("Enter an index value"); try { do { input = (char)System.in.read(); data = data + input; }while(input!='\n'); } catch(Exception err) { System.out.println("Unable to obtain system input"); } try { index = Integer.parseInt(data.trim()); System.out.println("The value in the requested index : "+values[index]); } catch(NumberFormatException err) { System.out.println("Invalid Index"); } catch(ArrayIndexOutOfBoundsException err) { System.out.println("Requested Index Not Found"); } finally { System.out.println("--------End---------"); } } } In the above program, there is a pre-defined array of length 5. The user input is got as a String. It is then parsed into an int data type. The value in the array for this index is given as ouput. Here, the exceptions may be thrown While getting an input While trying to convert the input to an int data type While trying to access that index in the array The exception classes for the last two exceptions are NumberFormatException and ArrayIndexOutOfBoundsException respectively. So the try block encapsulating the parsing of the input and searching of the index has two catch blocks to handle these exceptions in their own different way. If input is not an integer, then output is Invalid Index --------End---------
Basic Java
24 .
If input is an integer, but index is out of range in the array, then output is Requested Index Not Found --------End--------Note that in both the cases, the finally block is executed. Packages: Java provides a mechanism for partitioning the classname into more manageable chunks. This mechanism is the package. The package is both a naming and a visibility comttrol mechanism. Classes can be defined inside a package that are not accessible by code outside the package. Class members can also be defined that are only exposed to other members of the same package. This is achieved with the help of package and access protection. Access Protection: Java provides many levels of protection to allow fine-grained control over the visibility of the variables and methods within classes, subclasses and packages. Packages add another dimension to access control. Classes and packages are both means of encapsulating and containing the namespace and scope of variables and methods. Packages act as containers for classes and other subordinate packages. Classes act as containers for data and code. The class is Javas smallest unit of abstraction. Java addresses four categories of visibility for class members. 1. Sub classes in the same package 2. Non Subclasses in the same package 3. Subclasses in different packages 4. Classes are neither in the same package nor subclasses The three access specifiers, private, public and protected provide a variety of ways to produce tha many levels of access required by these categories. public - Anything declared public can be accessed from anywhere private Anything declared private cannot be seen outsideof its class. default When a member doesnot have an access specification, it is visible to subclasses as well as other classes in the same package. protected If an element has to be seen outside the current package but only to classes that subclass your class directly. Defining Package: Creating a package in Java is quite easy. This is achieved by simply including a package command as the first statement in a Java Source file. Any classes that are declared with in that file belong to the specified package. The package statement defines a namepsace in which classes are stored. If you omit the package statement, the classes are put into the default package that has no name.
Basic Java
25 .
Syntax for package statement: package mypackage; Use package keyword as the first line in the file. E.g. package com.first The classes under this package are in com/first namespace. The classes under this package must be stored inside the com/first folder Use import keyword for using the classes in different package. Example for Package mechanism: package com.first.one; public class BaseClass { int x=6; // default access private int x_pri=2; // private access protected int x_pro=3; //protected access public int x_pub=4; //public access public BaseClass() { System.out.println("Inside Constructor of Base Class"); } public void display() { System.out.println("Value of x(default) is "+x); System.out.println("Value of x(private) is "+x_pri); System.out.println("Value of x(protected) is "+x_pro); System.out.println("Value of x(public) is "+x_pub); } } package com.first.one; class Derived extends BaseClass { Derived() { System.out.println("Inside Derived Class Constrcutor\n"); System.out.println("Value of x(default) is "+x); // Not available to derived class also because it is private (Class only) // System.out.println("Value of x(private) is "+x_pri); System.out.println("Value of x(protected) is "+x_pro);
Basic Java
26 .
System.out.println("Value of x(public) is "+x_pub); } public static void main(String arg[]) { Derived deri=new Derived(); } } package com.first.one; public class TestBaseClass { public TestBaseClass() { System.out.println("Inside TestBaseClass constructor"); BaseClass bc1=new BaseClass(); System.out.println("Value of x(default) is "+bc1.x); // Not accessible because private - access is for Class only // System.out.println("Value of x(private) is "+bc1.x_pri); System.out.println("Value of x(protected) is "+bc1.x_pro); System.out.println("Value of x(public) is "+bc1.x_pub); } public static void main(String arg[]) { BaseClass bc=new BaseClass(); bc.display(); System.out.println("\n****************TestBaseClass************** *\n"); TestBaseClass test=new TestBaseClass(); } } package com.first.two; import com.first.one.BaseClass; class BaseClassNew extends BaseClass { BaseClassNew() { System.out.println("Constrcutor of Base class in another package"); //Not accessible because it is default - for package only //System.out.println("Value of x(default) is"+x); // Not accessible becuase it is private - for Class only //System.out.println("Value of x(private) is "+x_pri);
Basic Java
27 .
System.out.println("Value of x(protected) is "+x_pro); System.out.println("Value of x(public) is "+x_pub);
} public static void main(String arg[]) { BaseClassNew bcn=new BaseClassNew(); } } package com.first.two; import com.first.one.*; public class SomeClass { SomeClass() { System.out.println("Inside Constructor of SomeClass"); BaseClass bc=new BaseClass(); // Only for package //System.out.println("Value of x(default) is "+bc.x); // Only for Class //System.out.println("Value of x(private) is "+bc.x_pri); // Only for Class, subClass & package //System.out.println("Value of x(protected) is "+bc.x_pro); System.out.println("Value of x(public) is "+bc.x_pub); } public static void main(String arg[]) { SomeClass sc=new SomeClass(); } }
Basic Java
28 . Basic Java 29 .
Basic Java
30 .
THE MATH CLASS The Math class serves as a grouping of mathematical functions and constants. It is interesting to note that all the variables and methods in Math are static, and the Math class itself is final. This means you cant derive new classes from Math. Additionally, you cant instantiate the Math class. Its best to think of the Math class as just a conglomeration of methods and constants for performing mathematical computations. The Math class includes the E and PI constants, methods for determining the absolute value of a number, methods for calculating trigonometric functions, and minimum and maximum methods, among others. EXAMPLE FOR MATH CLASS public class MathExample { public static void main(String args[]) { char temp = (char)-1; String input = ""; Double data = null; System.out.println("Enter any number"); /** Gets the user input**/ try { do { temp = (char)System.in.read(); input = input + temp; }while(temp != '\n'); data = new Double(input); } catch(Exception err) { System.out.println("Exception ..."); System.exit(0); } double d_data = data.doubleValue(); System.out.println("Printing Math values......"); System.out.println("Sin : " + (Math.sin(d_data))); System.out.println("Cos : " + (Math.cos(d_data))); System.out.println("Tan : " + (Math.tan(d_data))); System.out.println("asin : " + (Math.asin(d_data))); System.out.println("acos : " + (Math.acos(d_data))); System.out.println("atan : " + (Math.atan(d_data))); System.out.println("Abs : " + (Math.abs(d_data))); System.out.println("Exp : " + (Math.exp(d_data))); System.out.println("Log : " + (Math.log(d_data))); System.out.println("Sqrt : " + (Math.sqrt(d_data))); System.out.println("Ceil : " + (Math.ceil(d_data))); System.out.println("Floor : " + (Math.floor(d_data))); System.out.println("rint : " + (Math.rint(d_data)));
Basic Java
31 .
System.out.println("round : " + (Math.round(d_data))); System.out.println("Random Number : " + (Math.random())); } } STRING CLASSES For various reasons (mostly security related), Java implements text strings as classes, rather than forcing the programmer to use character arrays. The two Java classes that represent strings are String and StringBuffer. The String class is useful for working with constant strings that cant change in value or length. The StringBuffer class is used to work with strings of varying value and length. THE STRING CLASS The String class represents character strings. All string literal in Java programs, such as "abc", are implemented as instances of this class. Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared. For example: String str = "abc"; is equivalent to: char data[] = {'a', 'b', 'c'}; String str = new String(data); Here are some more examples of how strings can be used: System.out.println("abc"); String cde = "cde"; System.out.println("abc" + cde); String c = "abc".substring(2,3); The class String includes methods for examining individual characters of the sequence, for comparing strings, for searching strings, for extracting substrings, and for creating a copy of a string with all characters translated to uppercase or to lowercase. The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuffer class and its append method. String conversions are implemented through the method toString(), defined by Object and inherited by all classes in Java. EXAMPLE FOR STRING CLASS public class StringExample { public static void main(String args[]) { String str = new String("Java World"); int length = str.length(); System.out.println("Length of data : "+length); System.out.println("Extracting character..."); for(int index=0;index<length;index++) { char temp = str.charAt(index); System.out.println(temp);
Basic Java
32 .
} System.out.println("Substring from 3rd position : " +(str.substring(3))); System.out.println("Substring from 3rd to 5th position : " +(str.substring(3,6))); System.out.println("Index of Wor : " + (str.indexOf("Wor"))); System.out.println("Converting to Upper Case : " + (str.toUpperCase())); System.out.println("Replacing 'a' with '*' : " + (str.replace('a','*'))); System.out.println("--------End-------"); } } THE STRINGBUFFER CLASS A string buffer implements a mutable sequence of characters. String buffers are safe for use by multiple threads. The methods are synchronized where necessary so that all the operations on any particular instance behave as if they occur in some serial order. String buffers are used by the compiler to implement the binary string concatenation operator +. For example, the code: x = "a" + 4 + "c" is compiled to the equivalent of: x = new StringBuffer().append("a").append(4).append("c").toString() The principal operations on a StringBuffer are the append and insert methods, which are overloaded so as to accept data of any type. Each effectively converts a given datum to a string and then appends or inserts the characters of that string to the string buffer. The append method always adds these characters at the end of the buffer; the insert method adds the characters at a specified point. For example, if z refers to a string buffer object whose current contents are "start", then the method call z.append("le") would cause the string buffer to contain "startle", whereas z.insert(4, "le") would alter the string buffer to contain "starlet". Every string buffer has a capacity. As long as the length of the character sequence contained in the string buffer does not exceed the capacity, it is not necessary to allocate a new internal buffer array. If the internal buffer overflows, it is automatically made larger. EXAMPLE FOR STRINGBUFFER public class SBExample { public static void main(String args[]) { String s = new String("Hello"); /** Constructors
Basic Java
33 .
1. Empty Constructor will create with initial capacity of 16 characters. 2. Constructor with specified characters as the initial capacity 3. Constructor with specified string as the initial value */ StringBuffer sb1 = new StringBuffer(); StringBuffer sb2 = new StringBuffer(40); StringBuffer sb3 = new StringBuffer(s); //Appending a boolean value sb1.append(true); System.out.println("Value of StringBuffer = " + sb1); //Appending a character sb1.append('c'); System.out.println("Value of StringBuffer = " + sb1); //Appending a character array char c[] = {'H','e','l','l','o'}; sb1.append(c); System.out.println("Value of StringBuffer = " + sb1); sb1.append(c,2,3); System.out.println("Value of StringBuffer = " + sb1); double d = 12.141354; sb1.append(d); System.out.println("Value of StringBuffer = " + sb1); float f = (float)15.1; sb1.append(f); System.out.println("Value of StringBuffer = " + sb1); int i = 1; sb1.append(i); System.out.println("Value of StringBuffer = " + sb1); long l = 1000000; sb1.append(l); System.out.println("Value of StringBuffer = " + sb1); sb1.append(s); System.out.println("Value of StringBuffer = " + sb1); System.out.println("Capacity = " + sb2.capacity()); System.out.println("Character at 5th position = " + sb1.charAt(5)); sb1.getChars(0,4,c,0); System.out.println("Chars extracted from Sb1 = " + c); //Insert the boolean value at the 5th position sb1.insert(5,true); //Insert the character value at the 9th position sb1.insert(9,'M');
Basic Java
34 .
System.out.println("Length of the string buffer = " + sb1.length()); sb1.reverse(); System.out.println("Reverse of the String Buffer = " + sb1); sb1.setCharAt(5, 'Y'); System.out.println("Value of String Buffer = " + sb1); } } THE SYSTEM AND RUNTIME CLASSES The System and Runtime classes provide a means for your programs to access system and runtime environment resources. Like the Math class, the System class is final and is entirely composed of static variables and methods. The System class basically provides a systemindependent programming interface to system resources. Examples of system resources include the standard input and output streams, System.in and System.out, which typically model the keyboard and monitor. The Runtime class provides direct access to the runtime environment. An example of a run-time routine is the freeMemory method, which returns the amount of free system memory available. EXAMPLE FOR RUNTIME public class RuntimeExample { public static void main(String args[]) { try { Runtime run = Runtime.getRuntime(); run.exec("notepad.exe"); } catch(Exception err) { System.out.println("Exception " +err.getMessage()); } } } THREAD CLASSES Java is a multithreaded environment and provides various classes for managing and working with threads. Following are the classes and interfaces used in conjunction with multithreaded programs: Thread ThreadDeath ThreadGroup Runnable The Thread class is used to create a thread of execution in a program. The ThreadDeath class is used to clean up after a thread has finished execution. As its name implies, the ThreadGroup class is useful for organizing a group of threads.
Basic Java
35 .
Finally, the Runnable interface provides an alternate means of creating a thread without subclassing the Thread class. CLASS CLASSES Java provides two classes for working with classes: Class and ClassLoader. The Class class provides runtime information for a class, such as the name, type, and parent superclass. Class is useful for querying a class for runtime information, such as the class name. The ClassLoader class provides a means to load classes into the runtime environment. ClassLoader is useful for loading classes from a file or for loading distributed classes across a network connection. Example to print the class name of an object: void printClassName(Object obj) { System.out.println("The class of " + obj + " is " + obj.getClass().getName());
}
Basic Java
36 .
CHAPTER- 3: THE UTILITIES PACKAGE java.util The Java utilities, package, which is also known as java.util, provides various classes that perform different utility functions. The utilities package includes a class for working with dates, a set of data structure classes, a class for generating random numbers, and a string tokenizer class, among others. The most important classes contained in the utilities package follow:
The Date Class Data Structure Classes The Random Class The StringTokenizer Class The Properties Class The Observer Interface The Enumeration Interface
THE DATE CLASS The Date class represents a calendar date and time in a system-independent fashion. The Date class provides methods for retrieving the current date and time as well as computing days of the week and month. EXAMPLE FOR DATE CLASS
import java.util.Date; public class DateExample { public static void main(String args[]) { String days[] = {"Sun","Mon","Tue","Wed","Thur","Fri","Sat"}; Date sys_date = new Date(); Date date = new Date(101,8,3); System.out.println("System Date : " + (sys_date.toString())); System.out.println("Specified Date : " + (date.toString())); int day = date.getDay();System.out.println("The day for the specified date : " + days[day]);System.out.println("Does the specified date precede the system date ? ");System.out.println(date.before(sys_date)); }}
Basic Java
37 .
Subclasses of Calendar interpret a Date according to the rules of a specific calendar system. The JDK provides one concrete subclass of Calendar: GregorianCalendar. Future subclasses could represent the various types of lunar calendars in use in many parts of the world. Like other locale-sensitive classes, Calendar provides a class method, getInstance, for getting a generally useful object of this type. Calendar's getInstance method returns a GregorianCalendar object whose time fields have been initialized with the current date and time:
THE RANDOM CLASS Many programs, especially programs that model the real world, require some degree of randomness. Java provides randomness by way of the Random class. The Random class implements a random-number generator by
Basic Java
38 .
providing a stream of pseudo-random numbers. A slot machine program is a good example of one that would make use of the Random class. EXAMPLE FOR RANDOM CLASS
import java.util.*; public class RandomExample { public static void main(String args[]) { Random random = new Random(); System.out.println("Random number(int):" + (random.nextInt())); System.out.println("Random number(float): " + (random.nextFloat())); System.out.println("Random number(double): " +(random.nextDouble())); System.out.println("Random number(gaussian): " +(random.nextGaussian())); Date date = new Date(); Random seed_random = new Random(date.getTime()); System.out.println("Random number with seed(int): " +(seed_random.nextInt())); System.out.println("Random number with seed(float): " +(seed_random.nextFloat())); System.out.println("Random number with seed(double): " + (seed_random.nextDouble())); System.out.println("Random number with seed(gaussian) : " +(seed_random.nextGaussian())); } }
Basic Java
39 .
(the characters that separate tokens) may be specified either at creation time or on a per-token basis. An instance of StringTokenizer behaves in one of two ways, depending on whether it was created with the returnTokens flag having the value true or false: If the flag is false, delimiter characters serve to separate tokens. A token is a maximal sequence of consecutive characters that are not delimiters. If the flag is true, delimiter characters are considered to be tokens. A token is either one delimiter character, or a maximal sequence of consecutive characters that are not delimiters. The following is one example of the use of the tokenizer. The code: StringTokenizer st = new StringTokenizer("this is a test"); while (st.hasMoreTokens()) { println(st.nextToken()); } prints the following output: this is a test
Basic Java
40 .
while(tokenizer.hasMoreTokens()) { System.out.println(tokenizer.nextToken()); } } }
Basic Java
41 .
Integer pos = new Integer(day); System.out.println("Day : " + (hash.get(pos).toString())); } } THE STACK CLASS The Stack class represents a last-in-first-out (LIFO) stack of objects. EXAMPLE FOR STACK CLASS import java.util.*; public class StackExample { public static void main(String args[]) { Stack stack = new Stack(); Date date = new Date(); StringTokenizer tokenizer = new StringTokenizer(date.toString()); System.out.println("tokens : "+tokenizer.countTokens()); while (tokenizer.hasMoreTokens()) { stack.push(tokenizer.nextToken()); } Object obj = stack.peek(); System.out.println("First element in stack - by peek : " + (obj.toString())); System.out.println("Pop out the elements in stack "); while(!stack.empty()) { obj = stack.pop(); System.out.println(obj.toString()); } } } THE VECTOR CLASS The Vector class implements a growable array of objects. Like an array, it contains components that can be accessed using an integer index. However, the size of a Vector can grow or shrink as needed to accommodate adding and removing items after the Vector has been created. Each vector tries to optimize storage management by maintaining a capacity and a capacityIncrement. The capacity is always at least as large as the vector size; it is usually larger because as components are added to the vector, the vector's storage increases in chunks the size of capacityIncrement. An application can increase the capacity of a vector before inserting a large number of components; this reduces the amount of incremental reallocation.
Basic Java
42 .
EXAMPLE FOR VECTOR CLASS import java.util.*; public class VectorExample { public static void main(String args[]) { Vector store = new Vector(); String input = ""; char temp = (char)-1; System.out.println("Enter a string "); try { do { temp = (char)System.in.read(); input = input+temp; }while(temp != '\n'); input = input.trim(); }catch(Exception err){} StringTokenizer tokenizer = new StringTokenizer(input); while(tokenizer.hasMoreTokens()) { store.addElement(tokenizer.nextToken()); } System.out.println("Size of the Vector : "+store.size()); System.out.println("Capacity of the Vector : "+store.capacity()); System.out.println("First Element : "+store.firstElement()); System.out.println("Last Element : "+store.lastElement()); Enumeration enum = store.elements(); while(enum.hasMoreElements()) { System.out.println(enum.nextElement().toString()); } store.trimToSize(); System.out.println("Capacity of the vector after trimming : " + (store.capacity())); } }
Basic Java
43 .
structures and algorithms. Because the various implementations of each interface are interchangeable, programs can be easily tuned by switching implementations.
Provides interoperability between unrelated APIs by establishing a common
interfaces.
Legacy Implementations - The collection classes from earlier releases, Vector and
implementations.
Convenience Implementations - High-performance "mini-implementations" of the
collection interfaces.
Abstract Implementations - Partial implementations of the collection interfaces to
Basic Java
44 .
sorting a list.
Infrastructure - Interfaces that provide essential support for the collection interfaces. Array Utilities - Utility functions for arrays of primitives and reference objects. Not,
strictly speaking, a part of the Collections Framework, this functionality is being added to the Java platform at the same time and relies on some of the same infrastructure. Collection Interfaces There are six collection interfaces. The most basic interface is Collection . Three interfaces extend Collection : Set , List , and SortedSet . The other two collection interfaces, Map and SortedMap , do not extend Collection , as they represent mappings rather than true collections. However, these interfaces contain collection-view operations, which allow them to be manipulated as collections. tion Collec The Collection interface is the root of the collection hierarchy. A ns implement. Collection is used to pass collections around and Set you Collection represents a group of objects, known as its elements. Some Collection implementations allow duplicate elements and others do not. Some are ordered and others unordered. The JDK doesn't provide any direct implementations of this interface: It provides implementations of more specific subinterfaces like Set List and . This interface is the least common denominator that all collectio manipulate them when maximum generality is desired. A Set is a collection that cannot contain duplicate elements. As might expect, this interface models the mathematical set abstraction. It is used to represent sets like the cards comprising a poker hand, the
Basic Java
45 .
courses making up a student's schedule, or the processes running on List in the List each element is inserted. The eir integer index (position). If you've List. ction interfaces (SortedSet and SortedMap) are merely sorted version Object le interface provides automatic natural order on classes that implement it, while SortedSet for things like word lists and Sorted its mappings in ascending key rowing a runtime exception (UnsupportedOperationException) if they are attempted. Imp their documentation which optional operations they support. Several terms are introduced to aid in this specification: modification operations (such as add, to as unmodifiable. Collections that are not Lists that guarantee that their size remains constant even though the are referred to as fixed-size. Lists that are not fixed-riable-size. a machine. A List is an ordered collection (sometimes called a sequence). Lists can contain duplicate elements. The user of a List generally has precise control over where user can access elements by th, you're already familiar with the general flavor of used VectorMap A Map is an object that maps keys to values. Maps cannot contain duplicate keys: Each key can map to at most one value. If you've used Hashtable, you're already familiar with the general flavor of Map. The last two core colle s of Set and Map Ordering There are two ways to order objects: The Comparab the Comparator interface gives the programmer complete control over object ordering. Note that these are not core collection interfaces, but underlying infrastructure. The last two core collection interfaces: A SortedSet is a Set that maintains its elements in ascending order. Several additional operations are provided to take advantage of the ordering. The SortedSet interface is used membership rolls. Map A SortedMap is a Map that maintains order. It is the Map analogue of SortedSet. The SortedMap interface is used for apps like dictionaries and telephone directories. All of the modification methods in the collection interfaces are labeled optional. Someimplementations may not perform one or more of these operations, th lementations must specify in Collections that do not support any remove and clear) are referred unmodifiable are referred to modifiable. Collections that additionally guarantee that no change in the Collection object will ever be visible are referred to as immutable. Collections that are not immutable are referred to as mutable. elements may change size are referred to as va
Basic Java
46 .
Some implementations may restrict what elements (or in the case of Maps , keys and values) may be stored. Possible restrictions include requiring elements to: Be of a particular type. Be non-null. Obey som edic e. Atte lement tha n imple entation's restrictions results in a runtime excep ClassCastException lArgum ntException or gh table below: Implementations e ar mpting to ad d an e tion, t violates a m e typically a , an Illega bitrary pr at
a NullPointerException. Attempting to remove or test for the presence of an elementthat violates an implementation's restrictions may result in an exception, thousome "restricted collections" may permit this usage. Collection Implementations Class that implement the collection interfaces typically have names of the form <Implementation-style><Interface>. The general-purpose implementations are summarized in the Hash TableResizable ArrayBalanced Tree Linked List Set HashSet TreeSet List ArrayList LinkedListInterfaces Map HashMap TreeMap The general-purpose implementations support all of the optional operations in the collection interfaces, and have no restrictions on the elements they may contain. The AbstractCollectionAbstractSetAbstractListAbstractSequentialList AbstractMap , , , and classes provide skeletal implementations of the core collection interfaces, to minimize the effort required to implement them. The API documentation for these classes describes precisely how each method is implemented so the De The ma an API that was reasonably small, both in size, and not , rather he same time, the new API had to be powerful eption to indicate that they do not support a specified optional operation. Of course, collection implementers must clearly document which optional operations are supported by an implementation. To keep the number of methods in each core interface small, an interface contains a method only if either: implementer knows which methods should be overridden, given the performance of the "basic operations" of a specific implementation. sign Goals in design goal was to produce , more importantly, in "conceptual weight." It was critical that the new functionality seem alien to current Java programmers; it had to augment current facilitiesthan replacing them. At t enough to provide all the advantages described above. To keep the number of core interfaces small, the interfaces do not attempt to capture such subtle distinctions as mutability, modifiability, resizability. Instead, certain calls in the core interfaces are optional, allowing implementations to throw an UnsupportedOperationExc
Basic Java
47 .
1. It is a truly fundamental operation: a basic opcould be reasonably defined, erations in terms of which others includes methods to allow i rrays, arrays to be viewed as collections, and maps to be w 2. There is a compelling performance reason why an important implementation would want to override it. It was critical that all reasonable representations of collections interoperate well. This included arrays, which cannot be made to implement the Collection interface directly ithout changing the language. Thus, the framework wcollect ons to be dumped into a vieed as collections.
Basic Java
classes for inputting streams of data, outputting , and tokenizing streams of data. The most s a ms. Java ile. The File class iles that takes into account system-dependent features. for reading and ing data to and from a file; it is only useful for querying and modifying the ibutes of a file. In actuality, you can think of the File class data as representing a ame, and the class methods as representing operating system commands that t on filenames. a variety of methods for reading and writing stances of this class represent the name of a file or directory on the host file ame, which can either be an absolute pathname directory. The pathname must follow tion that deals with most of the machin fashion Note th me or path is used it is assumed that the host's file ing . rt java.io.*; t java.util.Date; The Java I/O package, also known as java.io, provides classes witreading and writing data to and from different input and output devices, includin I/O package include he streams of data, working with filesant classes contained in the I/O package follows: import Input Stream Classes Output Stream Classes File Classes The StreamTokenizer Class FILE CLASSES re the most widely used method of data storage in computer syste Filesup ports files with two different classes: File and RandomAccessFprovides an abstraction for f The File class keeps up with information about a file including the location where it is stored and how it can be accessed. The File class has no methods writ attr filen ac The RandomAccessFile class provides d ata to and from a file. RandomAccessFile contains many different methods for reading and writing different types of information, namely the data type wrappers. HE FILE CLASS T In system. A file is specified by a pathn or a pathname relative to the current working the naming conventions of the host platform. The Fi le class is intended to provide an abstrac e dependent complexities of files and pathnames in a machine-independent . at whenever a filena conventions are used nam Example for File im poimpor public class FileExample { public static void main(String args[]) {
Basic Java
49 . if(args.length == 0) xample ing filename = args[0]; File file = new File(filename); ists()); date = new Date(file.lastModified()); Last Modified : "+date.toString()); System.out.println("Absolute Path : ile.getAbsolutePath()); System.out.println("Length of file : "+file.length()); n("Parent : "+file.getParent()); } TH CLASS Ins rt both reading and writing to a random access file. An app in the file at which the next read or write occurs. Thi rity by offering methods that allow specified mode acc te to files. Example for RandomAccessFile mp rt java.io.*; System.exit(0); File srcfile = new File(sourcefile); File destfile = new File(destinfile); RandomAccessFile srcrdm = new RandomAccessFile(srcfile,"r"); RandomAccessFile dstrdm =new RandomAccessFile(destfile,"rw"); { System.out.println("Usage : java FileE<filename>"); System.exit(0); } Str try { System.out.println("File Exists : "+file.ex Date System.out.println(" "+f
System.out.printl} c atch(Exception err) { System.out.println("Exception file"); } } E RANDOMACCESSFILE tances of this class suppo lication can modify the position f secu s class provides a sense o esses of read-only or read-wri o i public class RandomAccessExample { public static void main(String args[]) { if(args.length != 2) { System.out.println("Usage : "); System.out.println("java RandomAccessExample <sourcefile> <destfile>"); } String sourcefile = args[0]; String destinfile = args[1]; String data = ""; ry t{ in accessing
Basic Java
50 . System.out.println("The size of the file "+srcrdm.length()); System.out.println("The file pointer is at "+srcrdm.getFilePointer()); data = srcrdm.readLine(); intln("File successfully copied"); ystem.out.println("Open the destination file to view the reading data from an input source. An input ring, memory, or anything else that contains data. The input SequenceInputStream StringBufferInputStream counterpart to input streams and handle writing data to an input sources, output sources include files, strings, memory, n contain data. The output stream classes defined in java.io while(!data.equals("")) { dstrdm.writeBytes(data); data = srcrdm.readLine(); } ystem.out.pr S S result"); catch(Exception err) { } } }} INPUT STREAM CLASSES Java uses input streams to handle source can be a file, a ststream classes follow: InputStream BufferedInputStream ByteArrayInputStream tStream DataInpuFileInpu tStream putStream FilterIn LineNumberInputStream PipedInputStream PushbackInputStream The InputStream class is an abstract class that serves as the base class for all input streams. The InputStream class defines an interface for reading streamed bytes of data, finding out the number of bytes available for reading, and moving the stream position pointer, among other things. All the other input streams provide support for reading data from different types of input devices. UTPUT STREAM CLASSES O Output streams are the output source. Similar to anything else that ca and follow: OutputStream BufferedOutputStream ByteArrayOutputStream DataOutputStream
Basic Java
51 .
FileOutputStream FilterOutputStream Ou class that serves as the base class for all output n interface for writing streamed bytes of data o other output streams provide support for writing data to written by an output stream is formatted to be read by BUFFEREDINPUTSTREAM CLASS class implements a buffered input stream. By setting up such an input stream, stream without necessarily causing a call to the ad. The data is read by blocks into a buffer; ng args[]) { te buf[] = new byte[10]; tion e) { he class implements a buffered output stream. By setting up such an output stream, cau yte written. The data is written into b uffer reaches its capacity, e buffer output stream is closed, or the buffer output stream is explicity flushed. ing args[]) / Copy the string into a byte array ance, spider!\n); e[] buf = new byte[64]; PipedOutputStream PrintStream The tputStream class is an abstractam defines a streams. OutputStreutput source. All the to an different output devices. Dataput stream. an in E TH he T an application can read bytes from a nderlying system for each byte re u subsequent reads can access the data directly from the buffer. Example for BufferedInputStream import java.io.*; class BufferedExample { ublic static void main (Stri p BufferedInputStream in = new dInputStream(System.in); Buffereby try { in.read(buf, 0, 10); } catch (Excep System.out.println(Error: + e.toString()); } 0); System.out.println(s); String s = new String(buf, } } THE BUFFEREDOUTPUTSTREAM CLASS T an application can write bytes to the underlying output stream without necessarily sing a call to the underlying system for each b a uffer, and then written to the underlying stream if the b th E xample for BufferedOutputStream Class import java.io.*; class WriteStuff { public static void mai n (Str{
Basic Java
52 .
s.getBytes(0, s.length(), buf, 0); // Output the byte array (buffered) BufferedOutputStream out = new BufferedOutputStream(System.out); try { out.write(buf, 0, 64); out.flush(); } catch (Exception e) { System.out.println(Error: + e.toString()); an application read primitive Java data types from an a machine-independent way. An application uses a data ata that can later be read by a data input stream. ta input streams and data output streams represent Unicode strings in a format at is a slight modification of UTF-8. ll characters in the range '\u0001' to '\u007F' are represented by a single byte: he null character '\u0000' and characters in the range '\u0080' to '\u07FF' are e '\u0800' to '\uFFFF' are represented by three bytes: bits 12-1510bits 61110bits 0-5 he "standard" UTF-8 format are the d 3-byte formats are used. m and DataOutputStream Stream; ort java.io.File; mport java.io.IOException; public class DataIOApp { } } } THE DATAINPUTSTREAM CLASS A data input stream lets in underlying input stream output stream to write d Da th A 0bits 0-7 T represented by a pair of bytes: 110bits 6-1010bits 0-5 Characters in the rang 1110 The two differences between this format and tfollowing: The null byt e '\u0000' is encoded in 2-byte format rather than 1-byte, so that the encoded strings never have embedded nulls. yte, 2-byte, an Only the 1-b mple for DataInputStrea Exa ort java.io.DataInputStream; imp import java.io.DataOutputStream; Stream; import java.io.FileInputort java.io.FileOutput impmp ii
Basic Java
53 .
public static void main(String args[]) throws IOException { Stream outFile = new FileOutputStream(file); DataOutputStream outStream = new DataOutputStream(outFile); (true); t(123456); har('j'); Double(1234.56); tes were written"); ); aInputStream inStream = new DataInputStream(inFile); readBoolean()); .readInt()); nStream.readChar()); inStream.readDouble()); nput stream for reading data from a File or from a ple for FileInputStream ort java.io.*; lass ReadFile ublic static void main (String args[]) ream(Grocery.txt); n.read(buf, 0, 64); + e.toString()); ; File file = new File("test.txt"); FileOutput outStream.writeBoolean outStream.writeIn outStream.writeCtStream.write ou System.out.println(outStream.size()+" bytStream.close(); ou outFile.close(); InputStream inFile = new FileInputStream(file Filet Da System.out.println(inStream.stem.out.println(inStream Sy System.out.println(istem.out.println( Sy inStream.close(); File.close(); in file.delete(); } } THE FILEINPUTSTREAM CLASS A file input stream is an iescriptor. FileD Exam imp c { p { byte buf[] = new byte[64]; try { FileInputStream in = new FileInputSt i } catch (Exception e) { stem.out.println(Error: Sy } ing s = new String(buf, 0) Str System.out.println(s); }}
Basic Java
54 .
THE FILEOUTPUTSTREAM CLASS is an output stream fo A file output stream FileDescriptor. r writing data to a File or to a ead the user input byte buf[] = new byte[64]; y + e.toString()); ry putStream out = new FileOutputStream(Output.txt); ut.write(buf); atch (Exception e) toString()); tes read are a Stream; o.IOException; in(String args[]) throws IOException ArrayOutputStream(); tring s = "This is a test."; for(int i=0;i<s.length();++i) outStream.write(s.charAt(i)); System.out.println("outstream: "+outStream); Example for FileOutputStream import jav a.io.*; class WriteFile { public static void main (String args[]) { // R tr { System.in.read(buf, 0, 64); } catch (Exception e) { System.out.println(Error: } // Output the data to a file t { FileOut o } c { System.out.println(Error: + e. } } } THE BYTEARRAYINPUTSTREAM CLASS This class allows an application to create an input stream in which the bypplications can also read bytes from supplied by the contents of a byte array. A string by using a StringBufferInputStream. Example for Byte Array input/output stream import java.io.ByteArrayInput import java.io.ByteArrayOutputStream; import java.i public class ByteArrayIOApp { public static void ma { ByteArrayOutputStream outStream = new Byte S
Basic Java
55 .
System.out.println("size: "+outStream.size()); ByteArrayInputStream inStream; System.out.println("inStream has "+inBytes+" available byte inBuf[] = new byte[inBytes]; Buf,0,inBytes); bytes were read"); "+new String(inBuf)); ASS lass implements a character buffer that can be used as a characterinput . xample for CharArrayReader and Writer port java.io.CharArrayReader; for(int i=0;i<s.length();++i) System.out.println("outstream: "+outStream); am.size()); eam.toCharArray()); ngBuffer(""); ) != -1) inStream = new ByteArrayInputStream(outStream.toByteArray()); int inBytes = inStream.available(); bytes"); int bytesRead = inStream.read(inad+" System.out.println(bytesRe System.out.println("They are: } } BYTEARRAYOUTPUTSTREAM CL THE s class implements an output stream in which the data is written into a byte array. Thi The buffer automatically grows as data is written to it. The data can be retrieved using toByteArray() and toString(). THE CHARARRAYREADER CLASS This cm strea E im import java.io.CharArrayWriter; import java.io.IOException; public class CharArrayIOApp { public static void main(String args[]) throws IOException { CharArrayWriter outStream = new CharArrayWriter(); String s = "This is a test."; outStream.write(s.charAt(i)); System.out.println("size: "+outStre CharArrayReader inStream; inStream = new CharArrayReader(outStr int ch=0; StringBuffer sb = new Stri while((ch = inStream.read()sb.append((char) ch); s = sb.toString(); ystem.out.println(s.length()+" characters were read"); S System.out.println("They are: "+s); } }
Basic Java
56 .
THE LINENUMBERREADER CLASS mbers. A line is nsidered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or ed. ("LineNumberIOApp.java"); NumberReader(inFile); tLine); HE PUSHBACKINPUTSTREAM CLASS buffer before reading from the underlying input stream. ent of code should read an indefinite number f data bytes that are delimited by particular byte values. After reading the h it back, so that the next read operation ream; IOException m outStream = new tream(); s is a test."; i) i)); A buffered character-input stream that keeps track of line nu co a carriage return followed immediately by a linefe Example for LineNumberReader import java.io.LineNumberReader; import java.io.FileReader; im port java.io.BufferedWriter; import java.io.IOException; public class LineNumberIOApp { p ublic static void main(String args[]) throws IOException { FileRead er inFile = new FileReader LineNumberReader inLines = new Line String inputLine; while ((inputLine=inLines.readLine()) != null) { System.out.println(inLines.getLineNumber()+". "+inpu } } } T This class is an input stream filter that provides a buffer into which data can be "unread." An application may unread data at any time by pushing it back into the buffer, as long as the buffer has sufficient room. Subsequent reads will read all of the pushed-back data in the This functionality is useful when a fragm o terminating byte the code fragment can pus on the input stream will re-read that byte. Ex ample PushbackInputStream and OutputStream Classes imp ort java.io.PushbackInputStream; import java.io.ByteArrayInputStream; imp ort java.io.ByteArrayOutputStimport java.io.IOException; public class PushbackIOApp { public static void main(String args[]) throws { ByteArrayOutputStrea By teArrayOutputS String s = "Thi for(int i=0;i<s.length();++ outStream.write(s.charAt(
Basic Java
57 .
System.out.println("outstream: "+outStream); Stream.size()); ArrayInputStream inByteArray; yteArray = new Stream inStream; w PushbackInputStream(inByteArray); har ch = (char) inStream.read(); System.out.println("First character of inStream is "+ch); inStream.unread((int) 't'); ilable(); for(int i=0;i<inBytes;++i) inBuf[i]=(byte) inStream.read(); HE SEQUENCEINPUTSTREAM CLASS he sequence input stream class allows an application to combine several input inp tically switches to xa s[]) throws IOException f1 = new p.java"); eInputStream("FileIOApp.java"); System.out.println("size: "+out Byte inB ByteArrayInputStream(outStream.toByteArray()); PushbackInput inStream = ne c int inBytes = inStream.ava System.out.println("inStream has "+inBytes+" available bytes"); byte inBuf[] = new byte[inBytes]; System.out.println("They are: "+new String(inBuf)); } } T T streams serially and make them appear as if they were a single input stream. Each ut stream is read from, in turn, until it reaches the end of the stream. The sequence input stream class then closes that stream and automa the next input stream. mple for SequenceInputStream E import java.io.FileInputStream; import java.io.SequenceInputStream; mport java.io.IOException; i ublic class SequenceIOApp p { public static void main(String arg { am; SequenceInputStream inStre FileInputStream FileInputStream("ByteArrayIOApFileInputStream f2 = new Fil inStream = new SequenceInputStream(f1,f2); boolean eof = false; int byteCount = 0; hile (!eof) w { int c = inStream.read(); if(c == -1) eof = true;
Basic Java
58 .
else { System.out.print((char) c); ount+" bytes were read"); ; n input stream and parses it into "tokens", controlled by a ber of flags that can be set to various states. The stream tokenizer ntifiers, numbers, quoted strings, and various comment styles. regarded as a character in the range '\u0000' d to look up five possible attributes of the alphabetic, numeric, string quote, and comment character. character can have zero or more of these attributes. addition, an instance has four flags. These flags indicate: d. Whether the se. t constructs an instance of this class, sets up the syntax dly loops calling the nextToken method in each iteration of EOF. okenizer; reamReader; ic static void main(String args[]) throws IOException .in)); r(inData); ++byteCount; } } System.out.println(byteC inStream.close(); f1.close(); f2.close() } } THE STREAMTOKENIZER CLASS The StreamTokenizer class takes a allowing the tokens to be read one at a time. The parsing process is table and a num can recognize ide Each byte read from the input stream is through '\u00FF'. The character value is usecharacter: white space, Each In Whether line terminators are to be returned as tokens or treated as white space that merely separates tokens. Whether C-style comments are to be recognized and skipped. Whether C++-style comments are to be recognized and skippe characters of identifiers are converted to lowerca A typical application firsbles, and then repeate ta the loop until it returns the value TT_ Example for StreamTokenizer Class import java.io.StreamTport java.io.InputSt im import java.io.BufferedReader; OException; import java.io.I public class StreamTokenApp { ubl p { BufferedReader inData = new BufferedReader(new InputStreamReader(System StreamTokenizer inStream = new StreamTokenize
inStream.commentChar('#');
Basic Java
59 . boolean eof = false; int token=inStream.nextToken(); case inStream.TT_EOF: case inStream.TT_EOL: break; case inStream.TT_WORD: ("Word: "+inStream.sval); break; System.out.println("Number: "+inStream.nval); break; default: System.out.println((char) token+" encountered."); true; } t stream and aving the other thread read the data through a piped input stream. ile file = new File(filename); public class PipedExample { public static void main(String args[]) { if(args.length == 0) { System.out.println("Usage : java PipedExample <filename>"); System.exit(0); } String filename = args[0]; try { F FileInputStream fis = new FileInputStream(file); byte store[] = new byte[fis.available()]; byte p_store[] = new byte[fis.available()]; fis.read(store,0,store.length); do { switch(token) { System.out.println("EOF encountered."); eof = true; break; System.out.println("EOL encountered."); System.out.println case inStream.TT_NUMBER: if(token=='!') eof= } while(!eof); } } THE PIPEDINPUTSTREAM CLASS A piped input stream is the receiving end of a communications pipe. Two threads can communicate by having one thread send data through a piped outpu h Example for Piped Input/Output Operations import java.io.*;
Basic Java
60 .
PipedOutputStream piped_out = new PipedOutputStream(); PipedInputStream piped_in = new PipedInputStream(piped_out); piped_out.write(store,0,store.length); ystem.out.println("Result stored in file 'output.txt'"); ("ouput.txt"); 0,p_store.length); ---"); or use in debugging, and for compatibility with PrintWriter class. -serializable classes will be initialized using piped_in.read(p_store,0,p_store.length); S FileOutputStream fos = new FileOutputStream fos.write(p_store, System.out.println("----------End-----} catch(Exception err) { System.out.println("Exception in accessing file"); } } } THE PRINTSTREAM CLASS Print values and objects to an output stream, using the platform's default character encoding to convert characters into bytes. If automatic flushing is enabled at creation time, then the stream will be flushed each time a line is terminated or a newline character is written. Methods in this class never throw I/O exceptions. Client code may inquire as to hether any errors have occurred by invoking the checkError method. w Note: This class is provided primarily fxisting code; new code should use the e THE SERIALIZABLE INTERFACE Serializability of a class is enabled by the class implementing the java.io.Serializable interface. Classes that do not implement this interface will not have any of their state serialized or deserialized. All subtypes of a serializable class are themselves serializable. The serialization interface has no methods or fields and serves only to identify the semantics of being serializable. To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype'spublic, protected, and (if accessible) package fields. The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class's state. It is an error to declare a class Serializable in this case. he error will be detected at runtime. T uring deserialization, the fields of non D thepublic or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream.
Basic Java
61 .
When traversing a graph, an object may be encountered that does not support the Serializable interface. In this case the NotSerializableException will be thrown and will identify the class of the non-serializable object. Classes that require special handling during the serialization and deserialization process must implement special methods with these exact signatures: private void writeObject(java.io.ObjectOutputStream out) r writing the state of the object for its articular class so that the corresponding readObject method can restore it. The riteObject. The method does not need to concern itself with the state elonging to its superclasses or subclasses. State is saved by writing the individual adObject ethod uses information in the stream to assign the fields of the object saved in the DataOutput. HE EXTENALIZABLE INTERFACE to write the object's nd to read them back. The Externalizable interface's plemented by a class to give the class tents of the stream for an object and its ust explicitly coordinate with the supertype to save its ate. ject to be stored is tested for e Externalizable interface. If the object supports it, the writeExternal method is HE OBJECTINPUTSTREAM CLASS serializes primitive data and objects previously written using utStream can provide an of objects when used with a throws IOException private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException; The writeObject method is responsible fo p default mechanism for saving the Object's fields can be invoked by calling out.defaultW b fields to the ObjectOutputStream using the writeObject method or by using the methods for primitive data types supported by DataOutput. The readObject method is responsible for reading from the stream and restoring the classes fields. It may call in.defaultReadObject to invoke the default mechanism for restoring the object's non-static and non-transient fields. The defaultRe m stream with the correspondingly named fields in the current object. This handles the case when the class has evolved to add new fields. The method does not need to concern itself with the state belonging to its superclasses or subclasses. State is saved by writing the individual fields to the ObjectOutputStream using the writeObject method or by using the methods for primitive data types supported by T Externalization allows a class to specify the methods to be used contents to a stream a writeExternal and readExternal methods are im complete control over the format and con supertypes. These methods m st Object Serialization uses the Serializable and Externalizable interfaces. Object persistence mechanisms may use them also. Each ob th called. If the object does not support Externalizable and does implement Serializable the object should be saved using ObjectOutputStream. When an Externalizable object is to be reconstructed, an instance is created using thepublic no-arg constructor and the readExternal method called. Serializable objects are restored by reading them from an ObjectInputStream. T An ObjectInputStream de an ObjectOutputStream. ObjectOutputStream and ObjectInp application with persistent storage for graphs
Basic Java
62 .
FileOutputStream and FileInputStream respectively. ObjectInputStream is used to g the standard mechanisms. ut. lds declared as transient or static re ignored by the deserialization process. References to other objects cause those g constructors are voked for the nonserializable classes and then the fields of the serializable classes the serializable class closest to va.lang.object and finishing with the object's most specifiec class. the example in ObjectOutputStream: putStream("t.tmp"); utStream(istream); ject(); Object(); tion to save and restore ation and deserialization process should am stream) ream stream) FoundException; recover those objects previously serialized. Other uses include passing objects between hosts using a socket stream or for marshaling and unmarshaling arguments and parameters in a remote communication system. ObjectInputStream ensures that the types of all objects in the graph created from the stream match the classes present in the Java Virtual Machine. Classes are loaded as required usin Only objects that support the java.io.Serializable or java.io.Externalizable interface can be read from streams. The method readObject is used to read an object from the stream. Java's safe casting should be used to get the desired type. In Java, strings and arrays are objects and are treated as objects during serialization. When read they need to be cast to the expected type. Primitive data types can be read from the stream using the appropriate method on DataInp The default deserialization mechanism for objects restores the contents of each field to the value and type it had when it was written. Fie a objects to be read from the stream as necessary. Graphs of objects are restored correctly using a reference sharing mechanism. New objects are always allocated when deserializing, which prevents existing objects from being overwritten. Reading an object is analogous to running the constructors of a new object. Memory is allocated for the object and initialized to zero (NULL). No-ar in are restored from the stream starting with ja For example to read from a stream as written by FileInputStream istream = new FileIn ObjectInputStream p = new ObjectInp int i = p.readInt(); String today = (String)p.readOb Date date = (Date)p.read istream.close(); Cla sses control how they are serialized by implementing either thejava.io.Serializable or java.io.Externalizable interfaces. Imp lementing the Serializable interface allows object serializathe entire state of the object and it allows classes to evolve between t he time the stream is written and the time it is read. It automatically traverses refe rences between objects, saving and restoring entire graphs. Serializable classes that require special handling during the serializ im plement both of these methods: private void writeObject(java.io.ObjectOutputStre throws IOException; bjectInputSt private void readObject(java.io.O throws IOException, ClassNot
Basic Java
63 .
The readObject method is responsible for reading and restoring the state of the written to the stream by the corresponding not need to concern itself with the state sses. State is restored by reading data from the individual fields and making assignments to the object. Reading primitive data types is supported by taInput. t plement the java.io.Serializable interface. Subclasses of Objects that are not able class must have a se it is the responsibility class. It is le (public, package, or get and set methods that can be used to restore the exception that occurs while deserializing an object will be caught by the ectInputStream and abort the reading process. e lized form. The methods of e interface, writeExternal and readExternal, are called to save and ts state. When implemented by a class they can write and read their sing all of the methods of ObjectOutput and ObjectInput. It is the the objects to handle any versioning that occurs. ObjectInputStream; ObjectOutputStream; Serializable; FileInputStream; FileOutputStream; File; rt java.io.IOException; args[]) throws IOException, t.txt"); tream outFile = new FileOutputStream(file); jectOutputStream outStream = new ectOutputStream(outFile); ',0.0001,"java"); s is a test."; te(); object for its particular class using data writeObject method. The method does belonging to its superclasses or subcla the ObjectInputStream for appropriate fields of the Da Serialization does not read or assign values to the fields of any object that does no im serializable can be serializable. In this case the non-serializ no-arg constructor to allow its fields to be initialized. In this ca of the subclass to save and restore the state of the non-serializable frequently the case that the fields of that class are accessib protected) or that there are state. y AnObj Im plementing the Externalizable interface allows the object to assume complettrol over the contents and format of the object's seria con the Externalizabl objec restore the own state u responsibility of Example for ObjectInput and Output Streams import java.io. import java.io. import java.io. import java.io. import java.io.ort java.io. impmpo i import java.util.Date; public class ObjectIOApp {
public static void main(String ClassNotFoundException { = new File("tes File file ileOutputS FOb bj O TestClass1 t1 = new TestClass1(true,9,'Aests2 t2 = new TestClass2(); TClas String t3 = "Thi Date t4 = new Da
Basic Java
64 .
outStream.writeObject(t1); eam.writeObject(t2); tStream.close(); putStream(file); = new ObjectInputStream(inFile); println(inStream.readObject()); stem.out.println(inStream.readObject()); ystem.out.println(inStream.readObject()); System.out.println(inStream.readObject()); inFile.close(); lass TestClass1 implements Serializable double d; this.i = i; lueOf(c)+" "; } ializable estClass1 tc2; outStr outStream.writeObject(t3); outStream.writeObject(t4); ou outFile.close(); FileInputStream inFile = new FileIn ObjectInputStream inStream System.out. Sy S inStream.close(); file.delete(); } } c { boolean b; int i; char c; String s; TestClass1(boolean b,int i,char c,double d,String s) { this.b = b; this.c = c; this.d = d; this.s = s; } public String toString() { String r = String.valueOf(b)+" "; r += String.valueOf(i)+" "; r += String.va r += String.valueOf(d)+" "; r += String.valueOf(s); return r; } class TestClass2 implements Ser { int i; TestClass1 tc1; T
Basic Java
65 . TestClass2() tc1 = new TestClass1(true,2,'j',1.234,"Java"); A"); String r = String.valueOf(i)+" "; r += tc1.toString()+" "; n be written to streams. he class of each serializable object is encoded including the class name and n to the stream using the appropriate methods . an object writes the class of the object, the nt and non-static fields. References FileOutputStream ostream = new FileOutputStream("t.tmp"); tStream p = new ObjectOutputStream(ostream); p.writeObject("Today"); { i=0; tc2 = new TestClass1(false,7,'J',2.468,"JAV } public String toString() { r += tc2.toString(); return r; } } THE OBJECTOUTPUTSTREAM CLASS An ObjectOutputStream writes primitive data types and graphs of Java objects to an OutputStream. The objects can be read (reconstituted) using an ObjectInputStream. Persistent storage of objects can be accomplished by using a file for the stream. If the stream is a network socket stream, the objects can be reconsituted on another host or in another process. Only objects that support the java.io.Serializable interface ca T signature of the class, the values of the object's fields and arrays, and the closure of any other objects referenced from the initial objects. The method writeObject is used to write an object to the stream. Any object, including Strings and arrays, is written with writeObject. Multiple objects or primitives can be written to the stream. The objects must be read back from the corresponding ObjectInputstream with the same types and in the same order as they were written. Primitive data types can also be writteom DataOutput. Strings can also be written using the writeUTF method fr The default serialization mechanism for lass signature, and the values of all non-transie c to other objects (except in transient or static fields) cause those objects to be written also. Multiple references to a single object are encoded using a reference sharing mechanism so that graph of objects can be restored to the same shape as when the original was written. For example to write an object that can be read by the example in ObjectInputStream: ObjectOutpu p.writeInt(12345); p.writeObject(new Date()); p.flush(); ostream.close();
Basic Java
66 .
Classes that require special handling during the serialization and deserialization these exact signatures: throws IOException, ClassNotFoundException; eObject method is responsible for writing the state of the object for its thod can restore it. The itself with the state belonging to the object's by writing the individual fields to the ethod or by using the methods for lization does not write out the fields of any object that does not implement the .io.Serializable interface. Subclasses of Objects that are not serializable can be erializable. In this case the nonserializable class must have a no-arg constructor to the responsibility of the subclass to alizable class. It is frequently the case that rm. The methods of the Externalizable n InputStreamReader is a bridge from byte streams to character streams: It reads platform's efault encoding may be accepted. Each invocation of one of an InputStreamReader's read() methods may cause one or more bytes to be read from the underlying byte-input stream. For top efficiency, consider wrapping an InputStreamReader within a BufferedReader; for example, BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); Example for InputStreamReader import java.io.InputStreamReader; import java.io.BufferedReader; process must implement special methods with private void readObject(java.io.ObjectInputStream stream) private void writeObject(java.io.ObjectOutputStream stream) throws IOException The writ par ticular class so that the corresponding readObject memethod does not need to concern superclasses or subclasses. S tate is saved ObjectOutputStream using the writeObject m primitive data types supported by DataOutput. Seria java s a llow its fields to be initialized. In this case it is save and restore the state of the non-seri th e fields of that class are accessible (public, package, or protected) or that there are get and set methods that can be used to restore the state. Serialization of an object can be prevented by implementing writeObject and re adObject methods that throw the NotSerializableException. The exception will be caught by the ObjectOutputStream and abort the serialization process. Implementing the Externalizable interface allows the object to assume complete control over the contents and format of the object's serialized fo in terface, writeExternal and readExternal, are called to save and restore the objects state. When implemented by a class they can write and read their own state using all of the methods of ObjectOutput and ObjectInput. It is the responsibility of the objects to handle any versioning that occurs. THE INPUTSTREAMREADER CLASS A b ytes and translates them into characters according to a specified characterencoding. The encoding that it uses may be specified by name, or the d
Basic Java
67 .
import java.io.IOException; public class InputConversionApp { public static void main(String args[]) throws IOException { InputStreamReader in = new InputStreamReader(System.in); BufferedR eader inStream = new BufferedReader(in); intln("Encoding: "+in.getEncoding()); ne; tem.out.println(inputLine); } while (inputLine.length() != 0); EAMWRITER CLASS ranslating characters into bytes according to a h OutputStreamWriter incorporates its own ter streams to byte streams. The en may be specified by name, by providing a CharToByteConverter, or by accepting the default encoding, which is defined by the invocation of a write() method causes the encoding converter to be invoked on e given character(s). The resulting bytes are accumulated in a buffer before being ing output stream. The size of this buffer may be specified, but y default it is large enough for most purposes. Note that the characters passed to (System.out)); System.out.pr String inputLi do { System.out.print(">"); System.out.flush(); inputLine=inStream.readLine(); Sys } } THE OUTPUTSTR Write characters to an output stream, t specified character encoding. Eac CharToByteConverter, and is thus a bridge from charac coding used by an OutputStreamWriter system property file.encoding. Each th written to the underly b the write() methods are not buffered. For top efficiency, consider wrapping an OutputStreamWriter within a BufferedWriter so as to avoid frequent converter invocations. For example, Writer out = new BufferedWriter(new OutputStreamWriter
Basic Java
68 .
CHAPTER 5: APPLET PROGRAMMING a Web page or viewed by the Java Applet their
r. and applications. The most important of an existing class. This class is called e to extend Applet in order for a class to be usable as for which is ou should see that the applet HelloWorld is quite different tion. ation , you ran them using the Java r, don't run from the command line; they are executed applet into the browser, you need to embed what are s" WIDTH ="200" HEIGHT="200"> at the file name be the same as the class file. This is HTML file can contain several An applet is a small program that is intended not to be run on its own, but rather to be embedded inside another application. The Applet class must be the superclass of ny applet that is to be embedded in a Viewer. The Applet class provides a standard interface between applets andnvironment. e elloWorld Applet H pplets can be run in a browser such as Netscape Navigator, Internet Explore A Several differences exist between applets hese is that Java applet classes extend t java.applet.Applet. You havuch. s ne of the simplest applets is the HelloWorld applet, the source code O shown below. Right away y from the HelloWorld applica HelloApplet.java import java.applet.Applet; import java.awt.Graphics; public class HelloApplet extends Applet { public void paint (Graphics g) { g.drawString ("Hello World!",0,50); } } Creating HTML file hen you created the HelloWorld applic W interpreter. Applets, howeveithin a browser. To get the w known as HTML tags into an HTML file. The HTML file can then be read into a browser. The simplest HTML file for the HelloApplet class is shown. HTML> < <BODY> APPLET CODE="HelloApplet.clas < </APPLET> </BODY> </HTML> ith Java files, it is necessary th W not necessary with the HTML file. In fact, a single APPLET> tags. <
Basic Java
69 .
Using AppletViewer ow, to run the applet, the JDK includes a very simplified version of a browser called o run the HelloApplet program using Appletviewer, on the command line type: lloApplet in it. CE CODE port java.applet.Applet; he import statement is a new one. Often it is necessary or easier to use the ce t work yourself. The import statement enables you to use these other classes. If ou are familiar with the C/C++ #include declaration, the import statement works in is specific to applets. In fact, in order for any class to be run in browser as an applet, it must extend java.applet.Applet. hics class. va.awt.Graphics contains all kinds of tools for drawing things to the screen. In fact, lass lass that xtends another class is placed at the bottom of the existing chain. ublic class HelloApplet extends Applet { ou may think this is harping the issue, but it's important: all applets must extend still have xtended it using the full name: ublic class HelloApplet extends java.applet.Applet { N Appletviewer. Appletviewer looks for <APPLET> tags in any given HTML file and opens a new window for each of them. T appletviewer HelloApplet.html Appletviewer opens a new window and runs He UNDERSTANDING THE SOUR Importing Other Classes The first thing to notice are the top two lines of the code: im import java.awt.Graphics; T contents of a class file, which have already been created, rather than try to reprodu tha y somewhat the same way. In the case of the HelloApplet program, there are two classes that are used other than HelloApplet. The first is the java.applet.Applet class. The Applet class contains all the information that a The second class that is imported into HelloApplet is the java.awt.Grap ja the screen is treated as a Graphics object. Declaring an Applet C You may have noticed that there is a slight difference between this class declaration for the HelloApplet class. HelloApplet extends Applet. extends is the keyword for saying that a class should be entered into that class hierarchy. In fact, a c e p Y java.applet.Applet. However, because you imported the Applet class, you can simply call it Applet. If you had not imported java.applet.Applet, you could e p
Basic Java
70 .
Applet Methodspaint he next item to notice about the HelloApplet class versus HelloWorld is that er lies in the fact that the applets don't start up themselves. They are being dded to an already running program (the browser). The browser has a predefined eans for getting each applet to do what it wants. It does this by calling methods that paint. e the browser needs to display the applet on the screen, so you can use the paint method to display anything. The browser helps out by passing a Graphics object to the paint method. This object gives the paint method a way to display items directly to the screen. The next line shows an example of using the Graphics object to draw text to the screen: g.drawString ("Hello World!",0,50); } BRIEF LIFE OF AN APPLET The paint method is not the only method that the browser calls of the applet. You can override any of these other methods just like you did for the paint method in the HelloWorld example. When the applet is loaded, the browser calls the init() method. This method is only called once no matter how many times you return to the same Web page. After the init() method, the browser first calls the paint() method. This means that if you need to initialize some data before you get into the paint() method, you should do so in the init() method. Next, the start() method is called. The start() method is called every time an applet page is accessed. This means that if you leave a Web page and then click the Back button, the start() method is called again. However, the init() method is not. When you leave a Web page (say, by clicking a link), the stop() method is called. Finally, when the browser exits all together the destroy() method is called. Notice that unlike the paint(Graphics g) method, the init(), start(), stop(), and destroy() methods do not take any parameters between the parentheses. The java.applet.AppletContext Interface This interface corresponds to an applet's environment: the document containing the applet and the other applets in the same document. The methods in this interface can be used by an applet to obtain information about its environment. T HelloApplet doesn't have a main method. Instead, this applet only has a paint method. How is this possible? The answ a m it knows the Applet has. One of these is public void paint (Graphics g) { The paint method is called any tim
Basic Java
71 .
The java.applet.AppletStub Interface When an applet is first created, an applet stub is attached to it using the applet's Multiple is mixed gether to produce a composite. setStub method. This stub serves as the interface between the applet and the browser environment or applet viewer environment in which the application is running. The java.applet.AudioClip Interface The AudioClip interface is a simple abstraction for playing as ound clip.AudioClip items can be playing at the same time, and the resulting sound to
Basic Java
72 .
Object ComponeContainerPanel Button Window TextComponeTextFieldDialog Frame MenuCompone Choice List TextArea MenuItemMenu MenuBar
Basic Java
73 .
A Simple AW T Applet import java.awt.*; import java.applet.Applet; public class Example1 extends Applet add(hiButton); ght=100></applet> ton component is created with the label, Click Me! this case an applet). prisingly little e is hidden behind the e g basic components, its relatively easy to keep things simple. to extend the functionality of the basic components, the e increases. ainer. A container is omponents (and even other containers) can e placed. This can go on endlessly: A component is added to a container, which is omponents are the building blocks from which all programs using the AWT are built. bet Thi gs about all components: terface components encompass all of the standard widgets or controls normally ssociated with a windowing system. Examples of these include buttons, text labels, crollbars, pick lists, and text-entry fields. { Button hiButton; public void init() { hiButton = new Button(Click Me!); } } applet code=Example1.class width=250 hei < It is not important at this point to understand exactly what every line means. Instead, try to get a general feel for what is going on. The example is doing the following: 1. A But 2. The Button is added to the container (inFor a program with a user interface that prod uces output, there is surcode here. Almost all the real work of handling the user interfac scnes. If you are usi nHowever, if you want complexity of your cod When a component is created, it usually is added to a cont simply an area of the screen in which c b added to another container, and so on. We will, in fact, be doing just this in the calculator example at the end of the chapter. This flexibility is one of the biggest advantages of programming the AWT. In an object-oriented programming environment, it makes sense to think of the user interface as actual objects and concentrate on relationships between objects. This is exactly what the AWT lets you do. Components C There are many other classes to handle the components and the interactions ween them, but if its on the screen, its a component. s enables us to say a number of thin All components have a screen position and a size All components have a foreground and background color Components are either enabled or disabled There is a standard interface for components to handle events AWT components can be conceptually broken down into three major categories: Interface components In a s
Basic Java
74 .
Containers ontainers encompass areas in which components can be placed. This allows
together to form a more cohesive object to be anipulated. A Panel is an example of this type of component. indows are a very special case of the Component class. All other components are ow is an actual, separate dow with a completely new area to create an interface upon. Normally with applet logs and Frames are examples of this type bstract base class for all plication to draw onto components that are realized state information needed for the basic rendering e following The Component object on which to draw. A translation origin for rendering and clipping coordinates. utput device. rations, which render horizontal text render the ove the baseline coordinate. the right from the path it traverses. This has the e occupies one extra he right and bottom edges as compared to filling a figure that is l line along the same y coordinate as the baseline of a line entirely below the text, except for any descends. nts to the methods of this Graphics object in of this Graphics object prior to the vocation of the method. All rendering operations modify only pixels, which lie within ip of the graphics context and the extents of component used to create the Graphics object. All drawing or writing is done in t font. C groups of components to be grouped m Windows W added onto a container that already exists, whereas a Wind win programming, windows are not used. Dia of c omponent. Th e java.awt.Graphics classThe Graphics class is the agraphics contexts that allow an ap on various devices, as well as onto off-screen images. A Graphics object encapsulates operations that Java supports. This state information includes thperties: pro The current clip. The current color. The current font. The current logical pixel operation function (XOR or Paint). The current XOR alternation color . oordinates are infinitely thin and lie between the pixels of the o C Operations, which draw the outline of a figure, operate by traversing an infinitely thin path between pixels with a pixel-sized pen that hangs down and to the right of the nchor point on the path. Operations, which fill a figure operate by filling the interior a of that infinitely thin path. Opescending portion of character glyphs entirely ab a The graphics pen hangs down and tollowing implications: fo If you draw a figure that covers a given rectangle, that figur
row of pixels on tbounded by that same rectangle. If you draw a horizontaof text, that line is drawn All coordinates, which appear as argume considered relative to the translation orig are in the area bounded by both the current cl the the current color, using the current paint mode, and in the curren
Basic Java
75 .
Example for using Graphics class blic class GraphicsExample extends Applet aphics g) raphics class",50,50); 10); .drawOval(90,60,10,10); 60,10,10,6,6); fillOval(90,90,10,10); red, blue, green components of a color are each represented by an integer in the range 0- . The value 0 indicates no contribution from this primary color. The value 255 lor component. on the three-component RGB model, the class B colors. mple for Using Color class mport java.applet.Applet; ublic void init() .drawString("Example for Color class",50,50); 0,10,10); d); import java.awt.Graphics; import java.applet.Applet; pu { public void paint(Gr { g.drawString("Example for G g.drawRect(60,60,10, g g.drawRoundRect(120, g.fillRect(60,90,10,10); g. g.fillRoundRect(120,90,10,10,6,6); } } The java.awt.Color class This class encapsulates colors using the RGB format. In RGB format, the and5 25 indicates the maximum intensity of this co Although the Color class is based provides a set of convenience methods for converting between RGB and HS Exa import java.awt.*; i public class ColorExample extends Applet { Color c_green; p { c_green = new Color(0,255,0); } public void paint(Graphics g) { g g.drawRect(60,6 g.setColor(Color.reg.drawOval(90,60,10,10);
Basic Java
76 .
g.drawRoundRect(120 ,60,10,10,6,6); .setColor(c_green); xample for Font Class ont font; aphics g) nds Object implements Serializable infinite recursion when your subclass is used. In ) getMaxAdvance() g g.fillRect(60,90,10,10); g.fillOval(90,90,10,10); g.fillRoundRect(120,90,10,10,6,6); } } The java.awt.Font Class A class that produces font objects. E import java.awt.*; import java.applet.Applet; public class FontExample extends Applet { F public void init() { font = new Font("Helvetica",Font.BOLD+Font.ITALIC,15); } ublic void paint(Gr p { g.setFont(font); g.drawString("Text Displayed in Helvetica font",25,50); } } The java.awt.FontMetrics class ublic abstract class FontMetrics exte p A font metrics object, which gives information about the rendering of a particular font on a particular screen. Note that the implementations of these methods are inefficient, they are usually overridden with more efficient toolkit-specific implementations. Note to subclassers: Since many of these methods form closed mutually recursive loops, you must take care that you implement at least one of the methods in each uch loop in order to prevent s particular, the following is the minimal suggested set of methods to override in order to ensure correctness and prevent infinite recursion (though other subsets are equally feasible): getAscent() getDescent() getLeading(
Basic Java
77 .
charWidth(char ch) charsWidth(char data[], int off, int len) When an application asks AWT to place a character at the position (x, y), the haracter is placed so that its reference point is put at that position. The reference he baseline of the character. In normal rinting, the baselines of characters should align. amount by which the character ascends above the baseline. idth is w, then the following character is placed with its ference point at the position (x + w, y). The advance width is often the same as the ing can also have an ascent, a descent, and an e array is the maximum ascent of any character in e array. The . A label displays a single rocessMouseEvent, or it can register itself as a listener for mouse events by calling ods are defined by Component, the abstract t to od c point specifies a horizontal line called t p In addition, every character in a font has an ascent, a descent, and an advance idth. The ascent is the w The descent is the amount by which the character descends below the baseline. The advance width indicates the position at which AWT should place the next character. If the current character is placed with its reference point at the position (x, y), and the character's advance w re width of character's bounding box, but need not be so. In particular, oblique and italic fonts often have characters whose top-right corner extends slightly beyond the advance width. An array of characters or a strdvance width. The ascent of th a the array. The descent is the maximum descent of any character in thdvance width is the sum of the advance widths of each of the characters in the a array. The java.awt.LabelClass A Label object is a component for placing text in a containere of readonly text. The text can be changed by the application, but a user cannot lin edit it directly. The java.awt.Button Class This class creates a labeled button. The application can cause some action to happen when the button is pushed. The gesture of clicking on a button with the mouse is associated with one instance of ActionEvent, which is sent out when the mouse is both pressed and released over the button. If an application is interested in knowing when the button has been pressed but not released, as a separate gesture, it can specialize p addMouseListener. Both of these methuperclass of all components. s When a button is pressed and released, AWT sends an instance of ActionEvene button, by calling processEvent on the button. The button's processEvent meth th receives all events for the button; it passes an action event along by calling its own processActionEvent method. The latter method passes the action event on to any action listeners that have registered an interest in action events generated by this utton. b
Basic Java
78 .
If an application wants to perform some action based on a button being pressed and tener and register the new listener to receive e button's addActionListener method. The ction command as a messaging protocol. he java.awt.TextComponent Class ublic class TextComponent
extends Component es a string of text. The TextComponent class s that determine whether or not this text is editable. If es another set of methods that supports a addition, the class defines methods that are used to maintain a current text selection, a substring of the component's text, rations. It is also referred to as the selected text. The jav public c
implements ItemSelectable hec nent that can be in either an "on" (true) or "off" se) state. Clicking on a check box changes its state from "on" to "off," or from "off" on." le creates a set of check boxes: the "on" state, and the other two are in the "off" state. In boxes are set independently. boxes can be grouped together under the control of a heckboxGroup class. In a check box group, at most one at any given time. Clicking on a check box to turn it on he same group that is on into the "off" state. up Class extends Object implements Serializable used to group together a set of Checkbox buttons. ox button in a CheckboxGroup can be in the "on" state at any released, it should implement ActionLis events from this button, by calling th application can make use of the button's a
T p The TextComponent class is the superclass of any component that allows the diting of some text. e text component embodi A defines a set of method the component is editable, it definxt insertion caret. te In selection from the text. The he target of editing ope is t
a.awt.Checkbox Class lass Checkbox extends Component k box is a graphical compo Ac (falo " t he following code examp T add(new Checkbox("one", null, true)); add(new Checkbox("two")); dd(new Checkbox("three")); a he button labeled one is in T this example, the states of the three check ck Alternatively, several che single object, using the C
button can be in the "on" stateox in t forces any other check b o The java.awt.CheckboxGr public class CheckboxGroup is The CheckboxGroup class xactly one check b E given time. Pushing any button sets its state to "on" and forces any other button that is in the "on" state into the "off" state. The following code example produces a new check box group, with three check boxes:
Basic Java
79 .
CheckboxGroup cbg = new CheckboxGroup(); he java.awt.Choice ayed s the title of the menu. mport java.awt.*; ublic class ChoiceExample extends Applet hoice ColorChooser; ColorChooser = new Choice(); ColorChooser.add("Green"); . The list can choose either one item or multiple items. dd("JavaSoft"); st.add("Mars"); dd(lst); an item that is already m the scrolling list selected at a time, since the second argument when creating the new s any other selected item to be add(new Checkbox("one", cbg, true)); add(new Checkbox("two", cbg, false)); add(new Checkbox("three", cbg, false)); T public class Choice extends Component implements ItemSelectable The Choice class presents a popup menu of choices. The current choice is displ a Example for adding Choice i import java.applet.Applet; p { C public void init|() { ColorChooser.add("Red"); ColorChooser.add("Blue"); add(ColorChooser); } } The java.awt.List Class public class List extends Component implements ItemSelectable List component presents the user with a scrolling list of text items The be set up so that the user can For example, the code . . . List lst = new List(4, false); lst.add("Mercury"); lst.add("Venus"); d("Earth"); lst.adt.a lsl lst.add("Jupiter"); st.add("Saturn"); l lst.add("Uranus"); lst.add("Neptune"); d("Pluto"); lst.adnt.a c lects it. Clicking on Clicking on an item that isn't selected sedeselects it. In the preceding example, only one item fro selected n be ca scrolling list is false. Selecting an item causeautomatically deselected.
Basic Java
80 .
Beginning with Java 1.1, the Abstract Window Toolkit sends the List object all keyboard, and focus events that occur over it. (The old AWT event model is ing maintained only for backward compatibility, and its use is discouraged.) elected, AWT sends an instance of Item Event to the t. When the user double-clicks on an item in a scrolling list, AWT sends an instance nerates an action an application wants to perform some action based on an item in this list being ner or ActionListener as ppropriate and register the new listener to receive events from this list. ction scrolling lists, it is considered a better user interface to use an xternal gesture (such as clicking on a button) to trigger the action. s component represents a blank rectangular area of the screen onto which e application can draw or from which the application can trap input events from the n application must subclass the Canvas class in order to get useful functionality overridden in order tom graphics on the canvas. ublic class CanvasTest extends java.applet.Applet doodle = new MyCanvas(getSize().width, etSize().height); } public MyCanvas(int width, int height) { g) { MOUSE, be When an item is selected or des lis of ActionEvent to the list following the item event. AWT also ge event when the user presses the return key while an item in the list is selected. If selected or activated, it should implement ItemListe a For multiple sele e The java.awt.Canvas Class A Canva th user. A such as creating a custom component. The paint method must be to perform cus Example for Canvas Class import java.awt.*; p { MyCanvas doodle; public void init() { g add(doodle); } } class MyCanvas extends Canvas { public MyCanvas() { this(100,100); resize(width,height); } public void paint(Graphics
Basic Java
81 .
g.fillRect(0, 0, getSize().width-1, getSize().height-1); } } The java.awt.Scrollbar Class public class Scrollbar extends Component implements Adjustable The Scrollbar class embodies a scroll bar, a familiar user interface object. A scroll bar provides a convenient means for allowing a user to select from a range of values. le, if a scroll bar resent range of the scroll bar. The or ould be created with code like the following: HORIZONTAL, 0, 64, 0, 255); ximum value for the scroll bar's own, or click roll ba gestures can oll bar receives an instance djustmentListener, an interface defined in the package java.awt.event. e top arrow of a vertical scroll bar, or makes the The following code provides a sample model of scrollbar. redSlider=new Scrollbar(Scrollbar.VERTICAL, 0, 1, 0, 255); add(redSlider); Alternatively, a scroll bar can represent a range of values. For examp is used for scrolling through text, the width of the "bubble" or "thumb" can rep the amount of text that is visible. Here is an example of a scroll bar that represents a range: The value range represented by the bubble is the visibleizontal scroll bar in this example c h ranger = new Scrollbar(Scrollbar.add(ranger); ote that the maximum value above, 255, is the ma N bubble. The actual width of the scroll bar's track is 255 + 64. When the scroll bar is set to its maximum value, the left side of the bubble is at 255, and the right side is at 55 + 64. 2 theture with the Normally, user changes the value of the scroll bar by making a gesd d mouse. For example, the user can drag the scroll bar's bubble up an the scr's unit increment or block increment areas. Keyboard in also be mapped to the scroll bar. By convention, the Page Up and Page Down keys are equivalent to clicking in the scroll bar's block increment and block decrement areas. hen the user changes the value of the scroll bar, the scr W of AdjustmentEvent. The scroll bar processes this event, passing it along to any registered listeners. Any object that wishes to be notified of changes to the scroll bar's value should plement A im Listeners can be added and removed dynamically by calling the methods addAdjustmentListener and removeAdjustmentListener. The AdjustmentEvent class defines five types of adjustment event, listed here: AdjustmentEvent.TRACK is sent out when the user drags the scroll bar's bubble. AdjustmentEvent.UNIT_INCREMENT is sent out when the user clicks in the left rrow of a horizontal scroll bar, or th a equivalent gesture from the keyboard.
Basic Java
82 .
AdjustmentEvent.UNIT_DECREMENT is sent out when the user clicks in the right age Up ey is equivalent, if the user is using a keyboard that defines a Page Up key. EMENT is sent out when the user clicks in the track, the right of the bubble on a horizontal scroll bar, or below the bubble on a vertical nt, if the user is using a ge Down key. patibility, but its use with er versions of JDK is discouraged. The fives types of adjustment event pond to the five event types that are associated with ars in previous JDK versions. The following list gives the adjustment event .0 event type it replaces. LL_ABSOLUTE eplaces Event.SCROLL_LINE_UP NT replaces Event.SCROLL_LINE_DOWN T replaces Event.SCROLL_PAGE_UP NT replaces WN he java.awt.ScrollPane Class horizontal and/or vertical scrolling for r the scrollbars can be set to: as needed : scrollbars created and shown only when needed by scrollpane .always : scrollbars created and always shown by the scrollpane ver created or shown by the scrollpane objects (one rties (minimum, maximum, blockIncrement, and nally by the scrollpane in accordance with the geometry child and these should not be set by programs using the n the scrollpane can still be ethod and the scrollpane will ve and clip the child's contents appropriately. This policy is useful if the program ustable controls. rmspecific properties set by the but can be reset using setSize(). arrow of a horizontal scroll bar, or the bottom arrow of a vertical scroll bar, or makes the equivalent gesture from the keyboard. AdjustmentEvent.BLOCK_INCREMENT is sent out when the user clicks in the track, to the left of the bubble on a horizontal scroll bar, or above the bubble on a vertical scroll bar. By convention, the P k AdjustmentEvent.BLOCK_DECR to scroll bar. By convention, the Page Down key is equivale keyboard that defines a Pa The JDK 1.0 event system is supported for backward com new introduced with JDK 1.1 corres scroll b type, and the corresponding JDK 1 AdjustmentEvent.TRACK replaces Event.SCRO AdjustmentEvent.UNIT_INCREMENT r AdjustmentEvent.UNIT_DECREME AdjustmentEvent.BLOCK_INCREMENDECREME AdjustmentEvent.BLOCK_nt.SCROLL_PAGE_DO Eve T public class ScrollPane extends Container A container class, which implements automatic child component. The display policy fo a single . 1 2 3.never : scrollbars ne The state of the horizontal and vertical scrollbars is represented by two for each dimension) which implement the Adjustable interface. The API provides methods to access those objects such that the attributes on the Adjustable object (such as unitIncrement, value, etc.) can be manipulated. Certain adjustable propeisibleAmount) are set inter
v of the scrollpane and its scrollpane. If the scrollbar display policy is defined as "never", thegrammatically scrolled using the setScrollPosition() m proo m needs to create and manage its own adj The placement of the scrollbars is controlled by platfo user outside of the program. The initial size of this container is set to 100x100,
Basic Java
83 .
Insets are used to define any space used by scrollbars and any borders created by ets() can be used to get the current value for the insets. If the lue of the insets will change ot. ScrollPane pane; XCanvas xcan; setLayout(new BorderLayout()); ScrollPane(); add("Center", pane); pane.add(xcan); } } class public void paint(Graphics g) { g.drawLine(0, 0, 200, 200); } } bject implements Cloneable, Serializable n of the borders of a container. It specifies the leave at each of its edges. The space can be a border, a g[] args) (); w .add ; ); the scroll pane. getIns value of scrollbarsAlwaysVisible is false, then the vaamically depending on whether the scrollbars are currently visible or n dyn Example for ScrollPane Class import java.applet.Applet; import java.awt.*; pub lic class ScrollpaneTest extends Applet { public void init() { pane = new xcan = new XCanvas(); xcan.setSize(200, 200); XCanvas extends Canvas { g.drawLine(0, 200, 200, 0); The java.awt.Insets Class public class Insets extends On Insets object is a representatio A space that a container must lank space, or a title. b Example for Using Insets import java.awt.*; ass InsetTest cl { public static void main (Strin { = new MyFrame MyFrame win win.setLayout( new FlowLayout() ); in( new Button("One") ); win.add( new Button("Two") ) win.add( new Button("Three")
Basic Java
84 .
win.add( new Button("Four") ); wi pack(); t.println( win.insets() ); urn new Insets(100, 2, 2, 2); } sets insets() { return new Insets(25, 100, 2, 2); / public Insets insets() { return new Insets(25, 2, 100, 2); /public Insets insets() { return new Insets(25, 2, 2, 100); } from the outside world to the program that something clicks When the mouse button is clicked while positioned over a component. sent to the component informing it what coordinates in the component the mouse has d to. events A component that an action can be performed upon is used, an Action event by default and the owner of the component (usually the container in which the component is placed) is notified that something happened. to user actions. ublic class ActionEvent extends Applet { Button bt_submit; TextField data; it() submit = new B new Tex ubmit); n. win.show(); System.ou } } class MyFrame extends Frame { public Insets insets() { ret //public In } / } / } EVENT HANDLING An event is a communication has occurred. The following are a few basic event types: Mouse Mouse movement The mouse is moved over a component, many events are move Action is created One of the most important things to understand about the AWT is how events are handled. Without events, your application will not be able to respond Event Handling in JDK1.0 Example for using action import java.awt.*; a.applet.Applet; import jav p tf_ void in public { bt_ utton("SUBMIT");
tf_data = tField(15);
add(bt_s
Basic Java
85 . on Clicked"); line: ar to this. They accept a parameter of type Event bout the event. Second, they return a Boolean dled or False if it was not. it is the button. e if they are the Button Clicked) tton was clicked, we change the textfield to reflect that. ent was handled, return true or else return false. This is an important in mind: The event handler keeps searching for a method that will o use the event-handling methods that Sun has rized in Table below. Remember that everything component. For example, the mouseMove() method of a component he mouse is moved inside that component.
add(tf_data);
} public boolean action(Event evt, Object obj) { if(evt.target == bt_submit) { tf_data.setText("Butt } return true; } } Lets break the action() method down line by public boolean action(Event evt, Object what) { All event handlers have a form similat provides detailed information a th value-indicating True if the event was han(evt.target == bt_submit) { if Here the target of the event is being checked to see whether or not ecause evt.target and hiButton are both objects, we can check to se B same objects. tf_data.setText(ecause the bu B eturn true; r } lse e return false; Finally, if the evncept to keep co accept the Event. Accepting the Event is signaled by returning true. vent Handling in Detail E In almost all cases, you will want trovided for you. These are summa p is relative to the called when t is Java events. Event Type Method Action taken action(Event evt, Object what) mouseDown(Event evt, int x, int y) Mouse button pressed Mouse button released moved mouseMove(Event evt, int x, int y) useUp(Event evt, int x, int y)
Mouse mo Mouse dragged mouseDrag(Event evt, int x, int y) Mouse enters component mouseEnter(Event evt, int x, int y) ouse exits component mouseExit(Event evt, int x, int y) MKey pressed
keyDown(Event evt, int key) Basic Java 86 . Key released keyUp(Event evt, int key) When would yu actually wou want to use other methods than action()? The answer is that when ant to change the behavior of a component (as opposed to just using ponent as is was originally designed) action() isnt quite enough. It only vents that are essential to the utility of the component, such as a mouse public class Example3 extends Applet { ton; etLabel(Go Away!); ouseExit(Event evt, int x, int y) { hiButton.setLabel(Stay Away!); ject what) { ) { icked!); yo the comports e re click on a button. ets add new behavior to the previous example. L Adding new behavior to the sample applet. import java.awt.*; import java.applet.Applet; Button hiBut public void init() { hiButton = new Button(Click Me!!!); add(hiButton); } public boolean mouseEnter(Event evt, int x, int y) { hiButton.s return true; } public boolean m return true; } public boolean action(Event evt, Ob if (evt.target == hiButton hiButton.setLabel(Cl return true; } else
Basic Java
87 .
return false; } } e applet, the user is informed that perhaps licking on the button isnt such a good idea. This is a fundamentally different evious example. Before, we were using a button in a completely ere, we wished to change that functionality. This is important to other built-in event handlers will do the of the process ailable. es and disadvantages. On the positive side, you have u have complete control. This means that ault handleEvent() or your application can e buggy and confusing very quickly. ample, lets say you overrode handleEvent() in your class for whatever reason, u had used mouseEnter() earlier in the development of the program, as shown the following: n handleEvent(Event evt) ); ould expect the mouseEnter() you had written to keep working. Unfortunately ats not the case. Because the default handleEvent() has been overridden, <applet code=Example3.class width=250 height=100></applet> Now, whenever the mouse moves over th c behavior than the prstandard manner. H rememberotherwise, you might end up sub-classing components where you dont need to, making your program slower and more difficult to understand and maintain. handleEvent() or action() Generally, a combination of action() and theb nicely. For those times when you want to take complete control jo yourself, handleEvent() is avandleEvent() has advantag h complete control. On the negative side, yoou must be very careful overriding the def y becom For ext yo bu in Example using handleEvent class MyLabel extends Label { MyLabel(String label) { super(label); } public boolean mouseEnter(Event evt, int x, int y) { setText(Not Again); } public boolea { if (Event.id == KEY_PRESS) { setText(Keypress return true; } return false; else } }You w th
Basic Java
88 .
mouseEnter() never gets called. Luckily there is an easy solution to this problem for Event(evt); it of keeping all of the functionality of the old handleEvent() while tting you manipulate things first. Note, however, that you can also override handleEvent() to remove functionality, in which case you wouldnt want to call the p nt(). Its all up to you. Delivering Events O ability of the program to m events comes in quite h it may seem strange to fake an event, in reality it makes the design of a program much simpler. F designing a calcu t h ain container that deciphe ts from the button, as fp ction(Event evt, obj What) { if (evt.target == oneKey) the current number owever, it might make sense to add the ability to handle keyboard input, because a ty from a calculator. Although you just copy the code from the action() handler to a new keyDown() handler, you uld then have two copies of the same code in the same program to maintain and e target is the Object that you would like the event delivered to, id is an integer presenting the event type, and obj is an arbitrary argument to append to the event s the following: nt evt, int key) } ... many cases. Add the following to your handleEvent() in place of return false;: return super.handle This has the benef le arents handleEve ccasionally the andy. Although or example, if you were lator you migh andler in the m ollows: ublic boolean a t decide to write an evenrs the action even anufacture its own
... // Append 1 to } ... } H user of the calculator would expect that functionali could wo k eep track of. The solution is to deliver your own event. A simple event can be created with the following form: E vent aEvent = new Event (target, id, obj); Wher re if there is extra information that you would like the handler to receive. Then, to deliver the event, you just need to call deliverEvent() as follows: deliverEvent(aEvent); So, in the previous example, you could add another handler that doe
public boolean keyDown(Eve { if (key == 49) { // If the 1 key was Event(oneKey,Event.MOUSE_DOWN, null)); return true; }
pressed
deliverEvent(new
Basic Java
89 .
Now you can manage the rest of the program without worrying about handling eyboard input differentlythe same event is generated whether the button is clicked Event type Event IDs k or the correspond AWT event types. The Action event ACTION_EVENT Mouse button pressed MOUSE_DOWN Mouse dragged MOUSE_DRAG Mouse entered MOUSE_ENTER Mouse exited MOUSE_EXIT ouse button released MOUSE_UP Mouse moved MOUSE_MOVE M Key pressed y released KEY_RELEASE KEY_PRESS Ke Dealing with Focus hen a user clicks a user interface component, t W hat item becomes in a sense lected. This is as known as the input focus. For instance, when a text field is ked on, the user then can type in the field because it has the input focus. ocus() method of that en a component loses the input focus, the lostFocus() method of that component is not uncommon for a program to desire to keep the focus. For example, if a textan to accept input, you probably ceive the focus. Using a text-entry field to display utput enables you to take advantage of the fields text-handling abilities. In that shown in the following: r that the text field has been used in and would seic cl When a component receives the input focus, the gotFponent is called, as follows: com public boolean gotFocus(Event evt, Object what) { .. . } h W is called, as follows: public boolean lostFocus(Event evt, Object what) { ... } It entry field were being used to display output rather th would not want it to be able to re o case, the requestFocus() method exists, as public void requestFocus() { ... } is could be placed in the containe Th bar that field from receiving the focus.
Basic Java
90 .
Event Handling in JDK1.1 Event Handling in JDK 1.1 is through listeners. Listeners are provided as interfaces able the class to provide a later versions, the Event class is maintained only Applet Button b = new Button("I have a listener!"); ed(ActionEvent e) "Listener here: the button was vent e) java.applet.Applet; class AdjustmentEventTest extends Applet to enable multiple listeners to a class and also to en specific definition. . In Java 1.1 and for backwards compatibilty Example for using ActionListener import java.awt.Button; impor t java.applet.Applet; import java.awt.event.*; pub lic class ButtonDelegateTest extends{ public void init() { add(b); b.addActionListener(listener); } p ublic void actionPerform{ System.out.println(clicked."); } } The java.awt.event.ActionListener interface pu blic interface ActionListener extends EventListener The listener interface for receiving action events. Methods public abstract void actionPerformed(ActionE Invoked when an action occurs. Example for using AdjustmentListener mport i import java.awt.*; import java.awt.event.*; ublic p implements AdjustmentListener { c void init() publi{
Basic Java
91 . setLayout(new BorderLayout()); // A plain scrollbar that delegates to the applet. Scrollbar sbar1 = new Scrollbar(); ; dles its own adjustment events add(sbar2, "East"); ent e) ); SelfScrollbar extends Scrollbar { } ntEvent e) { e.getValue()); } port java.awt.event.*; t extends Applet ner { let. (); wn focus events (); nt e) { d gained focus"); ent e) { lost focus"); sbar1.addAdjustmentListener(this) add(sbar1, "West"); // A subclass that han SelfScrollbar sbar2 = new SelfScrollbar(); } public void adjustmentValueChanged(AdjustmentEv { System.out.println("Scrollbar #1: " + e.getValue() } } class { public SelfScrollbar() enableEvents(AWTEvent.ADJUSTMENT_EVENT_MASK); me public void processAdjustmentEvent (Adjust System.out.println("Scrollbar #2: " + } Example for using FocusEvent import java.applet.Applet;port java.awt.*; im im cusEventTes public class Fo implements FocusListe public void init() { setLayout(new BorderLayout()); s to the app // A textfield that delegate TextField tf = new TextField tf.addFocusListener(this); add(tf, "North"); its o // A subclass that handles SelfTextArea sta = new SelfTextArea add(sta, "Center"); } public void focusGained(FocusEveprintln("Text Fiel System.out. } public void focusLost(FocusEv System.out.println("Text Field }
Basic Java
92 .
} class SelfTextArea extends TextArea { public SelfTextArea() { enableEvents(AWTEvent.FOCUS_EVENT_MASK); } cusEvent e) { cusEvent.FOCUS_GAINED) n("Text Area gained focus"); System.out.println("Text Area lost focus"); } ener interface for receiving keyboard focus events on a component. blic abstract void focusGained(FocusEvent e) usEvent e) mport java.awt.*; ntTest extends Applet public void init() { applet. ; "); cotch"); list.addItem("Spumoni"); nts sc.addItem("Frozen Yogurt"); sc.addItem("Sorbet"); public void processFocusEvent(Fo if (e.getId() == Fo System.out.printl else } The java.awt.event.FocusListener interface The list pu public abstract void focusLost(Foc Example for using ItemListener import java.applet.Applet; i import java.awt.event.*; public class ItemEve implements ItemListener { List list; SelfChoice sc; // A list that dele gates to the list = new List(5, false); list.addItem("Chocolate"); list.addItem("Vanilla"); list.addItem("Strawberry") list.addItem("Mocha list.addItem("Peppermint Swirl"); list.addItem("Blackberry Ripple"); list.addItem("Butters list.addItemListener(this); add(list); // A choice subclass that handles its own item eve sc = new SelfChoice(); sc.addItem("Ice Cream");
Basic Java
93 .
add(sc); } public void itemStateChanged(ItemEvent e) { System.out.println("New item from list:" + Item()); public void processItemEvent(ItemEvent e) { m from choice: " + getSelectedItem()); he java.awt.event.ItemListener interface ce for receiving item events. ent e) xample for using KeyListener mport java.awt.*; tends Applet setLayout(new BorderLayout()); applet. es its own item events ; list.getSelected } } class SelfChoice extends Choice { public SelfChoice() { enableEvents(AWTEvent.ITEM_EVENT_MASK); } System.out.println("New ite } } T public interface ItemListener extends EventListener The listener interfa public abstract void itemStateChanged(ItemEv E import java.applet.Applet; i import java.awt.event.*; public class KeyEventTest exer { implements KeyListen public void init() { // A text field that delegates to the TextField tf = new TextField(); tf.addKeyListener(this); add(tf, "North"); // A text area subclass that handl SelfKeyTextArea sta = new SelfKeyTextArea() add(sta, "Center"); } public void keyTyped(KeyEvent e) { System.out.println("Key typed in text field: " + e.getKeyChar()); }
Basic Java
94 .
public void keyPressed(KeyEvent e) { } public void keyReleased(KeyEvent e) { } } class SelfKeyTextArea extends TextArea { public SelfKeyTextArea() { enableEvents(AWTEvent.KEY_EVENT_MASK); } public void processKeyEvent(KeyEvent e) { if (e.getId() == KeyEvent.KEY_TYPED) System.out.println("Key typed in text area: " + e.getKeyChar()); e listener interface for receiving keyboard events. ) t occurs when a key press is followed bstract void keyPressed(KeyEvent e) Applet nListener { e applet. ; // A canvas subclass that handles its own item events seCanvas(); } } } The java.awt.event.KeyListener interface c interface KeyListener extends EventListener publi Th public abstract void keyTyped(KeyEvent e Invoked when a key has been typed. This even by a key release. public a In voked when a key has been pressed. public abstract void keyReleased(KeyEvent e) Invoked when a key has been released. Example for using Mouse & MouseMotion Listeners import java.applet.Applet; import java.awt.*; import java.awt.event.*; p ublic class MouseEventTest extendsimplements MouseListener, MouseMotio public void init() { setLayout(new GridLayout(2, 1)); // A canvas that delegates to th Canvas can1 = new Canvas(); can1.setBackground(Color.yellow); can1.addMouseListener(this); can1.addMouseMotionListener(this) add(can1); SelfMouseCanvas can2 = new SelfMou add(can2);
Basic Java
95 .
public void mousePressed(MouseEvent e) { se pressed at " + e.getX() + "," + e.getY()); public void mouseReleased(MouseEvent e) { leased at " + e.getX() + "," + e.getY()); public void mouseEntered(MouseEvent e) { entered"); public void mouseClicked(MouseEvent e) { } // Ditto ) { } // Ditto nds Canvas { { een); t.MOUSE_EVENT_MASK | t.MOUSE_MOTION_EVENT_MASK); Event(MouseEvent e) { useEvent.MOUSE_PRESSED) e pressed at " + )); D) use released at " + () + "," + e.getY()); ener interface for receiving mouse events on a component. ) omponent. when a mouse button has been pressed on a component. System.out.println("UPPER: mou } System.out.println("UPPER: mouse re } System.out.println("UPPER: mouse } public void mouseExited(MouseEvent e) { } // Satisfy compiler public void mouseMoved(MouseEvent e public void mouseDragged(MouseEvent e) { } // Ditto } lass SelfMouseCanvas exte c public SelfMouseCanvas() (Color.gr setBackground enableEvents(AWTEven AWTEven } public void processMouse if (e.getId() == Mo System.out.println("LOWER: mous e.getX() + "," + e.getY(t.MOUSE_RELEASE else if (e.getId() == MouseEvenR: mo System.out.println("LOWE e.getX else if (e.getId() == MouseEvent.MOUSE_ENTERED) entered"); System.out.println("LOWER: mouse } } The java.awt.event.MouseListener interface nterface MouseListener extends EventListener public ilist The public abstract void mouseClicked(MouseEvent en clicked on a c Invoked when the mouse has bee bstract void mousePressed(MouseEvent e) public avoked In public abstract void mouseReleased(MouseEvent e) Invoked when a mouse button has been released on a component.
Basic Java
96 .
public abstract void mouseEntered(MouseEvent e) voked when the mouse enters a component. ublic abstract void mouseExited(MouseEvent e) voked when the mouse exits a component. nterface istener on a component. ponent and then dragged. Mouse rag events will continue to be delivered to the component where the first originated ntil the mouse button is released (regardless of whether the mouse position is within n a component (with no buttons o down). nt.*; et ut(2, 1)); // A text area that delegates to the applet. ); add(ta1); s its own item events lfTextTA(); add(ta2); public void textValueChanged(TextEvent e) { System.out.println("UPPER get text event: " + e); TextArea { stem.out.println("LOWER get text event: " + e); } In p In The java.awt.event.MouseMotionListener i public interface MouseMotionListener extends EventL The listener interface for receiving mouse motion events public abstract void mouseDragged(MouseEvent e) Invoked when a mouse button is pressed on a com d u the bounds of the component). public abstract void mouseMoved(MouseEvent e) Invoked when the mouse button has been moved o n Example for using TextListener import java.applet.Applet; import java.awt.*; import java.awt.eve public class TextEventTest extends Appl implements TextListener { public void init() { setLayout(new GridLayo TextArea ta1 = new TextArea(); ta1.addTextListener(this // A text area subclass that handle SelfTextTA ta2 = new Se } } } lass SelfTextTA extends c public SelfTextTA() { enableEvents(AWTEvent.TEXT_EVENT_MASK); } public void processTextEvent(TextEvent e) { Sy }
Basic Java
97 .
The java.awt.event.TextListener interface ends EventListener ner interface for receiving adjustment events. er interface extends EventListener r interface for receiving window events. indowEvent e) (WindowEvent e) indowEvent e) Activated(WindowEvent e) implements LayoutManager, Serializable in a left to right flow, much like lines of text in a to arrange buttons in a panel. It will ore buttons fit on the same line. Each line is public interface TextListener ext The liste public abstract void textValueChang ed(TextEvent e) Invoked when the value of the text has changed. The java.awt.event.WindowListen public interface WindowListener The listene p ublic abstract void windowOpened(WindowEvent e) Invoked when a window has been opened. public abstract void windowClosing(W In voked when a window is in the process of being closed. The close operation can be overridden at this point. public abstract void windowClosed(WindowEvent e) Invoked when a window has been closed. p ublic abstract void windowIconifiedInvoked when a window is iconified. public abstract void windowDeiconified(W In voked when a window is deiconified. public abstract void windowInvoked when a window is a ctivated. public abstract void windowDeactivated(WindowEvent e) In voked when a window is deactivated. AWT LAYOUTS The java.awt.FlowLayout class p ublic class FlowLayout extends ObjectA flow layout arranges components p aragraph. Flow layouts are typically used arrange buttons left to righ t until no mcentered.
Basic Java
98 .
Example for FlowLayout import java.awt.*; import java.applet.Applet; public class myButtons extends Applet { Button button1, button2, button3; FlowLayout flow; public void init() flow = new FlowLayout(FlowLayout.CENTER); button1 = new Button("Ok"); add(button2); ); he java.awt.BorderLayout class ect implements LayoutManager2, Serializable border layout lays out a container, arranging and resizing its components to fit in p.setLayout(new BorderLayout()); s a convenience, BorderLayout interprets the absence of a string specification the Layout()); p.add(new TextArea(), "Center"); sizes and the constraints of ents may be stretched horizontally; ically; the Center component ce left over. sing the BorderLayout layout import java.awt.*; t; public class buttonDir extends Applet { { setLayout(flow); button2 = new Button("Open"); button3 = new Button("Close"); add(button1); add(button3 } } A flow layout lets each component assume its natural (preferred) size. T public class BorderLayout extends Obj A five regions: North, South, East, West, and Center. When adding a component to a container with a border layout, use one of these five names, for example: Panel p = new Panel(); p.add(new Button("Okay"), "South"); A same as "Center": Panel p2 = new Panel(); p2.setLayout(new Border p2.add(new TextArea()); // Same as ording to their preferred The components are laid out acc the container's size. The North and South compon the East and West components may be stretched vert may stretch both horizontally and vertically to fill any spa u Here is an example of five buttons in an applet laid out manager: le for using BorderLayout Examp import java.applet.Apple public void init() {
Basic Java
99 .
setLayout(new BorderLayout()); ew Button("South")); add("East", new Button("East")); ter", new Button("Center")); } he java.awt.BorderLayout class ublic class BorderLayout extends Object implements LayoutManager2, Serializable arranging and resizing its components to fit in en adding a component to a s the absence of a string specification the ayout(new BorderLayout()); .add(new TextArea()); // Same as p.add(new TextArea(), "Center"); he components are laid out according to their preferred sizes and the constraints of uth components may be stretched horizontally; e East and West components may be stretched vertically; the Center component c class buttonDir extends Applet { public void init() { add("East", new Button("East")); } he java.awt.GridLayout class add("North", new Button("North")); add("South", n add("West", new Button("West")); add("Cen } T p A border layout lays out a container, five regions: North, South, East, West, and Center. Whtainer with a border layout, use one of these five names, for example: con p = new Panel(); Panel p.setLayout(new BorderLayout()); p.add(new Button("Okay"), "South"); As a convenience, BorderLayout interpret same as "Center": Panel p2 = new Panel(); p2.setL p2 T the container's size. The North and So th may stretch both horizontally and vertically to fill any space left over. Here is an example of five buttons in an applet laid out using the BorderLayout layout manager: Example for using BorderLayout import java.awt.*; import java.applet.Applet; publi setLayout(new BorderLayout()); add("North", new Button("North")); add("South", new Button("South")); add("West", new Button("West")); add("Center", new Button("Center")); } T public class GridLayout extends Object implements LayoutManager,
Basic Java
100 .
Serializable The GridLayout class is a layout manager that lays out a container's components in a rectangular grid. The container is divided into equalsized rectangles, and one component is placed in ach rectangle. import java.awt.*; port java.applet.Applet; public class ButtonGrid extends Applet add(new Button("4")); d(new Button("5")); add(new Button("6")); class class GridBagLayout extends Object implements LayoutManager2, erializable ach GridBagLayout object maintains a dynamic rectangular grid of cells, with each nt occupying one or more cells, called its display area. ponents' containers. g layout effectively, you must customize one or more of the ridBagConstraints objects that are associated with its components. You customize e For example, the following is an applet that lays out six buttons into three rows and two columns: Example for GridLayout im { public void init() { setLayout(new GridLayout(3,2)); add(new Button("1")); add(new Button("2")); add(new Button("3")); ad } } The java.awt.GridbagLayout public S The GridBagLayout class is a flexible layout manager that aligns components vertically and horizontally, without requiring that the components be of the same size. E compone Each component managed by a grid bag layout is associated with an instance of GridBagConstraints that specifies how the component is laid out within its display area. How a GridBagLayout object places a set of components depends on the GridBagConstraints object associated with each component, and on the minimum size and the preferred size of the com To use a grid ba G a GridBagConstraints object by setting one or more of its instance variables: gridx, gridy Specifies the cell at the upper left of the component's display area, where thepperleftmost cell has address gridx = 0, gridy = 0. Use u
Basic Java
101 .
GridBagConstraints.RELATIVE (the default value) to specify that the component be st placed just to the right of (for gridx) or just below (for gridy) the component that as added to the container just before this component was added. ridwidth, gridheight r gridheight) in the NDER to specify that the component be the last one in its (for gridwidth) or column (for gridheight). Use GridBagConstraints.RELATIVE to gridwidth) or column component's requested nent. Possible values are the default), GridBagConstraints.HORIZONTAL (make to fill its display area horizontally, but don't change its traints.VERTICAL (make the component tall enough to fill its hange its width), and GridBagConstraints.BOTH ea entirely). internal padding within the layout, how much to add to the width of the component will be at least its (since the padding applies to both sides of the f the component will be at least the minimum adding, the minimum amount of space between isplay area. r than its display area to determine where (within e the component. Valid values are R (the default), GridBagConstraints.NORTH, GridBagConstraints.EAST, GridBagConstraints.SOUTH, rmine how to distribute space, which is important for specifying resizing avior. Unless you specify a weight for at least one component in a row (weightx) column (weighty), all the components clump together in the center of their ntainer. This is because when the weight is zero (the default), the GridBagLayout object puts any extra space between its grid of cells and the edges of the container. ju w g Specifies the number of cells in a row (for gridwidth) or column (foponent's display area. The default value is 1. Use com GridBagConstraints.REMAI row specify that the component be the next to last one in its row (for (for gridheight). fill Used when the component's display area is larger than the size to determine whether (and how) to resize the compo GridBagConstraints.NONE ( the component wide enough height), GridBagCons display area vertically , but don't c(make the component fill its display ar ipadx, ipady Specifies the compone nt's minimum size of the component. Thexels minimum width plus (ipadx * 2) pi component). Similarly, the height o pixels. height plus (ipady * 2) insets Specifies the component's external p the edges of its d the component and anchor Used when the component is smalleo plac the display area) t.CENTE GridBagConstraints
GridBagConstraints.NORTHEAST, straints.SOUTHEAST, GridBagCon GridBagConstraints.SOUTHWEST, GridBagConstraints.WEST, and GridBagConstraints.NORTHWEST. weightx, weighty sed to dete U behd anco
Basic Java
102 .
Example for GridbagLayout import java.awt.*; public class Gridbag extends java.applet.Applet ayout gb = new GridBagLayout(); w GridBagConstraints(); out(gb); / gbc.fill= GridBagConstraints.HORIZONTAL; nchor= GridBagConstraints.NORTHWEST; gb.setConstraints(b, gbc); add(b); b = new Button("Third"); gbc.gridx = 3; gbc.gridwidth = GridBagConstraints.REMAINDER; gb.setConstraints(b, gbc); add(b); b = new Button("Fourth"); gbc.gridy++; gbc.gridx = 0; gb.setConstraints(b, gbc); add(b); b = new Button("Fifth"); gbc.gridwidth = 1; gbc.gridy++; gb.setConstraints(b, gbc); add(b); b = new Button("Sixth"); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 2; gb.setConstraints(b, gbc); add(b); } } { public void init() { GridBagL GridBagConstraints gbc = ne Button b; setLay / gbc.a gbc.gridwidth = 1; gbc.gridheight = 1; gbc.gridx = 0; gbc.gridy = 0; b = new Button("First"); gb.setConstraints(b, gbc); add(b); b = new Button("Second"); gbc.gridx = 1; gbc.gridwidth = 2;
Basic Java
103 .
To address the shortcomings of the AWT, the Java Foundation Classes (JFC) were eveloped. JFC 1.2 is an extension of the AWT, not a replacement of it. The JFC T container class. So the methods in the omponent & Container classes are still valid. JFC 1.2 consists of five major packages: Swing d-feel(PL&F) Drag and Drop 2D Sw w for efficient graphical user interface development. Swing Components are lightweight components. The major difference between lightweight a lightweight component can have transparent ixels while a heavywe ght component is always opaque. By taking advantage of ansparent pixels, a lightweight component can appear to be non-rectangular, while ust always be rectangular. A mouse event occuring in a hrough to its parent component, while a mouse event in snot propagate through its parent component. Swing ompliant. d visual components extend the AW C Pluggable Look-an Accessibility ing Swing components allo and heavyweight components is thati p tr a heavyweight component mghtweight component falls t li a heavyweight component doen C Components are Java Bea
javax.swing.plaf etc
The First Swing Program: import javax.swing.*; import java.awt.*; public class HelloSwing extends JFrame { JLabel text; public HelloSwing(S text = new getContent setVisible(true); } public static void main(String arg[]) HelloSwing swing = new Hewing"); S
Basic Java
105 .
creates a border with title "Border Example" LineBorder Soft Com ; der(Color.red,5)); n imgIcon = new ImageIcon("dot.gif"); = new MatteBorder(imgIcon); atte); -- f); ere,imgIcon); Other Borders MatteBorder EtchedBorder EmptyBorder BevelBorder BevelBorder poundBorder E xample of using Other Borders ---JPanel panel2, panel3 panel2 = new JPanel(); panel3 = new JPanel(); nel2.setBorder(BorderFactory.createLineBor paIco MatteBorder matte panel3.setBorder(m -Creating an ImageButton --Icon imgIcon = new ImageIcon(dot.giJButton imgBtn = new JButton(Click h --l displays a ImageButton with the image and the labe
Basic Java
106 .
Example Using JProgressBar mport java.awt.*; mport javax.swing.border.*; mport java.awt.event.*; ublic class UsingProgressBar extends JFrame implements ActionListener,Runnable { Button start; ProgressBar progress; nt count = 0; hread t = null; ublic UsingProgressBar(String title) for adding components t = new Thread(this); ionEvent event) { +count); tructor new DefaultMutableTreeNode("MDC ew "COMXpert"); w t"); first = new efaultMutableTreeNode("COM"); DefaultMutableTreeNode a_second = new DefaultMutableTreeNode("JAVA"); DefaultMutableTreeNode b_second = new DefaultMutableTreeNode("CORBA"); first.add(a_first); first.add(b_first); second.add(a_second); second.add(b_second); main.add(first); main.add(second); TreeModel model = new DefaultTreeModel(main); JTree tree = new JTree(model); import javax.swing.*; i i i p J J i T p { //code } Act public void actionPerformed( t.start(); } ublic void run() { p while(true) progress.setValue(+ } Example using JTree //code for class & cons DefaultMutableTreeNode main =Futura"); first = n DefaultMutableTreeNodeDefaultMutableTreeNode( D efaultMutableTreeNode second = neDefaultMutableTreeNode("CORBA XperDefaultMutableTreeNode a_first = new DefaultMutableTreeNode("ASP"); DefaultMutableTreeNode b_ D
Basic Java
107 .
//rest of code This displays a tree structure as follows: Using /code for class & constructor w Vector(); Vector colu ata.addElement(row); ow = new Vector(); t("CORBAXpert"); ow.addElement("JAVA & CORBA"); a.addElement(row); row.addElem t(row); "Course Contents"); JTable(data,column); /code to add the table JTable / Vector row = ne Vector data = new Vector(); mn = new Vector(); row.addElement("COMXpert"); row.addElement("ASP & COM"); d r row.addElemen r dat row = new Vector(); row.addElement("WEBXpert"); ent("COM & CORBA"); data.addElemen column.addElement("Course Name"); column.addElement(Table table = new J /
Basic Java
108 .
This displays a table as follows: he statement, he above statement listens to the Escape key press on the textfield tf_data and of the ActionListener ,16), "crosshair cursor"); Using Toolitp T setTooltipText(String text) is used to set the tooltip for a JComponent Example JButton btn = new JButton(Submit); btn.setTooltipText(Click here ); KeyStroke Handling : //code to be added tf_data.registerKeyboardAction(this,KeyStroke.getKeyStroke (KeyEvent.VK_ESCAPE,0),JComponent.WHEN_FOCUSED); T performs the code stated in the actionPerformed block C reating Custom Cursor The code block, --- Image img = getToolkit().getImage("duke.gif"); Cursor cr = getToolkit().createCustomCursor (img, new Point(16 b tn.setCursor(cr); --- creates a cursor with image of a duke. This cursor is made visible when the mouse is moved over the button.
Basic Java
109 .
lots of applets running at once on the same page. Depending on how many you have, you may eventually exhaust the system so that all of them will run slower, but all of them will run independently. Even if you dont have lots of applets, using threads in your applets is good Java programming practice. The general rule of thumb for well-behaved applets W
Basic Java
110 .
(such as an animation loop, or a bit of code that takes a long time to execute), put it You con l of the Java system can latt reem sus Non-preemptive , any scheduler has two fundamentally different ways of looking at its job: ote: non-preemptive scheduling, the scheduler runs the current thread forever, quiring that thread explicitly to tell it when it is safe to start a different thread. on-preemptive scheduling is very courtly, always asking for permission to schedule, time-critical, real-time applications where being terrupted at the wrong moment, or for too long, could mean crashing an airplane. r-priority threads, ven before their time-slice has expired. If you're going to depend on the priority of our threads, make sure that you test the application on both a Windows and e. can be assigned priorities, and when a choice is made between several reads that all want to run, the highest-priority thread wins. However, among threads at are all the same priority, the behavior is not well-defined. In fact, the different latforms on which Java currently runs have different behaviorssome behaving ore like a preemptive scheduler and some more like a non-preemptive scheduler. in a thread. T hread Scheduling The part of the system that decides the real-time ordering of threads is called the sch eduler. might wonder exactly what order your threads will be run in, and how you can trothat order. Unfortunately, the current implementations not precisely answer the former, though with a lot of work, you can always do the er. ptive Ver P Normally nonpreemptive scheduling and preemptive time-slicing. N With re With preemptive time-slicing, the scheduler runs the current thread until it has used up a certain tiny fraction of a second, and then preempts it, suspend()s it, and resume()s another thread for the next tiny fraction of a second. N and is quite valuable in extremely in Most modern schedulers use preemptive time slicing, because except for a few time-critical cases, it has turned out to make writing multithreaded programs much easier. For one thing, it does not force each thread to decide exactly when it should yield control to another thread. Instead, every thread can just run blindly on, knowing that the scheduler will be fair about giving all the other threads their chance to run. It turns out that this approach is still not the ideal way to schedule threads. Youve given a little too much control to the scheduler. The final touch many modern schedulers add is to enable you to assign each thread a priority. This creates a total ordering of all threads, making some threads more important than others. Being higher priority often means that a thread gets run more often (or gets more total running time), but it always means that it can interrupt other, lowe e y Macintosh or UNIX machin The current Java release does not precisely specify the behavior of its scheduler. Threads
th th p m
Basic Java
111 .
Writing Applets with Threads ow do you create an applet that uses threads? There are several things you need do. e four modifications you need to make to create an applet that uses threads: nstance variable to hold this applets thread. nothing but spawn a thread and start it Create a run() method that contains the actual code that starts your applet ep 1: change is to the first line of your class definition. s Runnable { port for the Runnable interface in your applet. re, the Runnable interface includes the behavior your applet needs to run a nable interface should be implemented by any class whose instances are ion, Runnable provides the means for while not subclassing Thread. A class that implements Runnable d by instantiating a Thread instance and passing most cases, the Runnable interface should be used if you are ride the run() method and no other Thread methods. This is sses should not be subclassed unless the programmer intends cing the fundamental behavior of the class. ublic abstract void run() nnable is used to create a thread, starting d to be called in that separately executing H to There ar Change the signature of your applet class to include the word implements Runnable. Include an i Modify your start() method to do running. running. t S The first You need to change it to the following: pletClass extends java.applet.Applet implement public class MyAp... } hat does this do? It includes sup W He thread; in particular, it gives you a default definition for the run() method. Before proceeding further, lets get on to the details of Runnable interface The java.lang.Runnable interface The Run intended to be executed by a thread. The class must define a method of no arguments called run. This interface is designed to provide a common protocol for objects that wish to execute code while they are active. For example, Runnable is implemented by class Thread. Being active simply means that a thread has been t yet been stopped. In addit started and has no class to be active a can run without subclassing Threa as the target. In itself inonly pl anning to over important because claifying or enhan on mod p When an object implementing interface Ruhe thread causes the object's run metho t thread. Step 2:
Basic Java
112 .
The second step is to add an instance variable to hold this applets thread. Call it anything you like; its a variable of the type Thread (Thread is a class in java.lang, so hread runner: r.start(); do nothing but spawn a thread, where does the body of your plet go? It goes into a new method, run(), which looks like this: ublic void run() { ble r garbage collection so that the applet can be removed from memory after a certain you dont have to import it): T S tep 3: Third, add a start() method or modify the existing one so that it does nothing but create a new thread and start it running. Heres a typical example of a start() method: public void start() { if (runner == null); { runner = new Thread(this); runne }} Step 4 : If you modify start() to ap p // what your applet actually does } run() can contain anything you want to run in the separate thread: initialization code, the actual loop for your applet, or anything else that needs to run in its own thread. You also can create new objects and call methods from inside run(), and theyll also run inside that thread. The run method is the real heart of your applet. Step 5: Finally, now that youve got threads running and a start method to start them, you should add a stop() method to suspend execution of that thread (and therefore whatever the applet is doing at the time) when the reader leaves the page. stop(), like start(), is usually something along these lines: public void stop() { if (runner != null) { runner.stop(); runner = null; } } The stop() method here does two things: it stops the thread from executing sets the threads variable (runner) to null. Setting the variable to null makes the Thread object it previously contained availa fo
Basic Java
113 .
amount of time. If the reader comes back to this page and this applet, the start thod creates a new thread and starts up the me applet once again. each of you is sharing some anaging that data, you could it. Now visualize a piece of code out it for a while, and then adds ut what to do += 1; t of the system at nce. The disaster occurs when two threads have both executed the if test before alue is clobbered by them ments has been lost. This d to you, but imagine instead that the crucial value affects the his disaster is inescapable if any significant part of the system has not been written r to a mainstream threaded hread safety. ratch with this is mind, and every Java class in its ve to worry only about your own ou can assume that the n threads of execution running concurrently. Every thread with higher priority are executed in preference to threads with er priority. Each thread may or may not also be marked as a daemon. When code ning in some thread creates a new Thread object, the new thread has its priority on thread if and nly if the creating thread is a daemon. , there is usually a single non-daemon thread hich typically calls the method named main of some designated class). The Java Now you have a well-behaved applet that runs in its own thread. T he Problem with Parallelism If threading is so wonderful, why doesnt every system have it? Many modern operating systems have the basic primitives needed to create and run threads, but ey are missing a key ingredient. The rest of their environment is not thread-safe. th Imagine that you are in a thread, one of many, and system. If you were m important data managed by the take steps to protect it but the system is managing in the system that reads some crucial value, thinks ab 1 to the value: if (crucialValue > 0) { // think abo . . . alue crucialV } Remember that any number of threads may be calling upon this par o either has incremented the crucialValue. In that case, the vrucialValue + 1, and one of the incre both with the same cay not seem so ba m state of the screen as it is being displayed. Now, unfortunate ordering of the threads can cause the screen to be updated incorrectly. In the same way, mouse or keyboard events can be lost, databases can be inaccurately updated, and so forth. T with threads in mind. Therein lies the barrientthe large effort required to rewrite existing libraries for t environme Luckily, Java was written from sc library is thread-safe. Thus, you now ha and thread-ordering problems, because y synchronization Java system will do the right thing. The java.lang.Thread Class cution in a program. The Java Virtual Machine allows a A thread is a thread of exeave multiple
application to hrity. Threads has a prio lown ru initially set equal to the priority of the creating thread, and is a daem o When a Java Virtual Machine starts up (w Virtual Machine continues to execute threads until either of the following occurs:
Basic Java
114 .
The exit method of class Runtime has been called and the security manager has e exit operation to take place. All threads that are not daemon threads have died, either by returning from the ng the stop method. arted. For example, thread that computes primes larger than a stated value could be written as follows: ends Thread { ime = minPrime; { mes larger than minPrime 3 ents the Runnable class then implements the run method. An instance of the class can gument when creating Thread, and started. The void run() { // compute primes larger than minPrime . . . } s enerated for it. permitted th call to the run method or by performi There are two ways to create a new thread of execution. One is to declare a class to be a subclass of Thread. This subclass should override the run method of class Thread. An instance of the subclass can then be allocated and st a class PrimeThread ext long minPrime; PrimeThread(long minPrime) { this.minPr } public void r un() // compute pri . . . } } The following code would then create a thr ead and start it running: PrimeThread p = new PrimeThread(14); p.start(); The other way to create a thread is to declare a class that implem interface. That then be a llocated, passed as an arsame example in this other style loo ks like the following: class PrimeRun implements Runnable { long minPrime; ng minPrime) PrimeRun(lo { minPrime; this.minPrime = } blic pu } The following code would then create a thread and start it running: PrimeRun p = new PrimeRun(143); new Thread(p).start(); Every thread has a name for identification purposes. More than one thread may have the same name. If a name is not specified when a thread is created, a new name i g
Basic Java
115 .
Constructors public Thread() Allocates a new Thread object. This constructor has the same effect as Thread(null, null, gname), where gname is a newly generated name. Automatically generated ames are of the form "Thread-"+n, where n is an integer. Threads created this way tually do anything. trating this method being used follows: } public void run() { System.out.println("A new thread with name " } d main(String args[] ) { (); System.out.println("new Thread() succeed"); else { System.out.println("new Thread() failed"); failed++; } public T t) Allocat hread-"+n, where n is an integer. has the same effect as Thread is a newly generated name. Automatically generated names are of the form "Thread-"+n, where n is an integer. public Thread(String name) n must have overridden their run() method to ac An example illus import java.lang.*; class plain01 implements Runnable { String name; plain01() { name = null; plain01(String s) { name = s; } if (name == null) System.out.println("A new thread created"); else + name + " created"); } class threadtest01 { public static voi int failed = 0 ; Thread t1 = new Thread if (t1 != null) } } ad(Runnable targe hre es a new Thread object. This constructor has the same effect as Thread(null, target, gname), where gname is a newly generated name. Automatically generated names are of the form "T public Thread(ThreadGroup group, Runnable target) Allocatehread object. This constructor s a new T (group, target, gname), where gname
Basic Java
116 .
Allocates a new Thread object. This constructor has the same effect as Thread(null, , name). e) structor has the same effect as Thread public Thread(Runnable target,String name) Allocates a new Thread object. This constructor has the same effect as Thread(null, target, public Thread( ) Allocates a new Thread object object, has the specified name as its na , an d to by group. If group is not null, checkAccess method of that thread group is called with no arguments; throwing a SecurityException; if group is null, the new process same group as the thread that is creating the new thread. read is started. The priority of ad creating it, tha to change the The newly created thread is initially marked the thread creating it is currently setDaemon may be used to c Example for u ss rstThread extends Thread public FirstThread(String name) super(name); catch(Exception err){} } } null public Thread(ThreadGroup group, String namcates a new Thread object. This con Allo (group, null, name) name). ThreadGroup group,Runnable target, String name so that it has target as its run d belongs to the thread group referre me the this may result inbelongs to the If the target argument is not null, the run method of the target is called when this thread is started. If the target argument is null, this thread's run method is called when this th the newly created thread is set equal to the priority of the thre t is, the currently running thread. The method setPriority may be usedpriority to a new value. as being a daemon thread if and only if marked as a daemon thread. The methodhange whether or not a thread is a daemon. sing Thread Class Fi cla { { } public void run() { for(int count System.out.println("count : "+count); System.out.println("First Thread in sleep state"); try { Thread.sleep(3000); } = 0;count<25;count++) if(count == 10) { {
Basic Java
117 .
} lass SecondThread extends Thread lic SecondThread(String name) { public void run() { for(int index = 0;index<25;index++) (Thread.activeCount())); System.out.println("Name of current thread : " +((Thread.currentThread()).getName( When dealing with multiple threads, consider this: What happens when two or more he same variable at the same time, and at least one of the } c{ pubsuper(name); } { System.out.println("***"); } } } public class ThreadExample{public static void main(String args[]) { FirstThread first = new FirstThread("first"); SecondThread second = new SecondThread("second"); System.out.println("Number of active threads : " + ))); first.start(); second.start(); } } Synchronization threads want to access t Threads wants to change the variable? If they were allowed to do this at will, chaos would reign. For example, while one thread reads Joe Smith's record, another thread tries to change his salary (Joe has earned a 50-cent raise). The problem is that this little change causes the Thread reading the file in the middle of the others update to see something somewhat random, and it thinks Joe has gotten a $500 raise. That's a great thing for Joe, but not such a great thing for the company, and probably a worse thing for the programmer who will lose his job because of it. How do you resolve this? The first thing to do is declare the method that will change the data and the method that will read to be synchronized. Java's key word, synchronized, tells the system to put a lock around a particular method. At most, one thread may be in any synchronized method at a time.
Basic Java
118 .
Two synchronized methods. public synchronized void setVar(int){ myVar=x; } public synchronized int getVar (){ return myVar; } Now, while in setVar() the Java VM sets a condition lock, and no other thread will be allowed to enter a synchronized method, including getVar(), until setVar() has finished. Because the other threads are prevented from entering getVar(), no thread will obtain information which is not correct because setVar() is in mid-write. The java.lang.ThreadGroup Class A thread group represents a set of threads. In addition, a thread group can also include other thread groups. The thread groups form a tree
in which every thread group except the initial thread group has a parent. A thread is allowed to access information about its own thread group, but not to access information about its thread group's parent thread group or any other thread groups. Constructors public ThreadGroup(String name) Constructs a new thread group. The parent of this new group is the thread group of the currently running thread. public ThreadGroup(ThreadGroup parent,String name) Creates a new thread group. The parent of this new group is the specified thread group. The checkAccess method of the parent thread group is called with no arguments; this may result in a security exception. The Daemon Property Threads can be one of two types: either a thread is a user thread or a Daemon thread. Daemon thread is not a natural thread, either. You can set off Daemon threads on a path without ever worrying whether they come back. Once you start a Daemon thread, you don't need to worry about stopping it. When the thread reaches the end of the tasks it was assigned, it stops and changes its state to inactive, much like user threads. A very important difference between Daemon threads and user threads is that Daemon Threads can run all the time. If the Java interpreter determines that only Daemon threads are running, it will exit, without worrying if the Daemon threads have finished. This is very useful because it enables you to start threads that do things such as monitoring; they die on their own when there is nothing else running. Two methods in java.lang.Thread deal with the Daemonic state assigned to a thread: Basic Java 119 . isDaemon() setDaemon(boolean) T he first method, isDaemon()isDaemon() true false , is used to test the state of a particular thread. Occasionally, this is useful to an object running as a thread so it can determine if it is running as a Daemon or a regular thread. returns if the thread is a Daemon, and otherwise. The second method, setDaemon(boolean), is used to change the daemonic state of e thread. To make a thread a Daemon, you indicate this by setting the input value t back to a user thread, you set the Boolean value to false. f is class only if it must clean up after being terminated asynchronously. If by a method, it is important that it be rethrown so that the read actually dies. th to true. To change i The java.lang.ThreadDeath Class An instance of ThreadDeath is thrown in the victim thread when the stop method with ero arguments in class Thread is called. An application should catch instances o zth ThreadDeath is caught th The top-level error handler does not print out a message if ThreadDeath is never caught. The class ThreadDeath is specifically a subclass of Error rather than Exception, even though it is a "normal occurrence", because many applications catch all occurrences of Exception and then discard the exception.
Basic Java
120 .
HAPTER 7: Networking in Java with remote systems. Much API within the java.net C
The Java execution environment is designed so that applications can be easily written to efficiently communicate and share processingf this functionality is provided with the standard Java o Thr investig pro co nteract is critical to developing network applications. Interne P is t ll data on the Internet flows through IP ackets, the basic unit of IP transmissions. IP is termed a connectionless, unreliable pro o before destina becaus ct corrupted data. These tasks ust be implemented by higher level protocols, such as TCP. package. TCP/IP Protocols eeprotocols are most commonly used within the TCP/IP scheme and a closer ation of their properties is warranted. Understanding how these three ls (IP, TCP, and UDP) i to t Protocol (IP) he keystone of the TCP/IP suite. A Ip tocl. As a connectionless protocol, IP does not exchange control information transmitting data to a remote systempackets are merely sent to the tion with the expectation that they will be treated properly. IP is unreliable e it does not retransmit lost packets or dete m IP defines a universal-addressing scheme called IP addresses. An IP address is a 32-bit number and each standard address is unique on the Internet. Given an IP packet, the information can be routed to the destination based upon the IP address defined in the packet header. IP addresses are generally written as four numbers, between 0 and 255, separated by period. (for example, 124.148.157.6) While a 32-bit number is an appropriate way to address systems for computers, umans understandably have difficulty remembering them. Thus, a system called the h Domain Name System (DNS) was developed to map IP addresses to more intuitive identifiers and vice-versa. You can use www.netspace.org instead of 128.148.157.6. It is important to realize that these domain names are not used nor understood by IP. When an application wants to transmit data to another machine on the Internet, it ust first translate the domain name to an IP address using the DNS. A receiving e translation, using the DNS to return a domain ame given an IP address. There is not a one-to-one correspondence between IP Jav m application can perform a revers n addresses and domain names: A domain name can map to multiple IP addresses, and multiple IP addresses can map to the same domain name. a provides a class to work with IP Addresses, InetAddress.
Basic Java
121 .
THE INETADDRESS CLASS This class represents an Internet Protocol (IP) address. Applications should use the the transport layer. TCP provides a liable, connection-oriented, continuous-stream protocol. The implications of these haracteristics are: uous-stream. TCP provides a communications medium that allows for stics, it is easy to see why TCP would be used by most ternet applications. TCP makes it very easy to create a network application, freeing efficiently provide reliable transmissions given e parameters of your application. Furthermore, retransmission of lost data may be appropriate for your application, because such information's usefulness may have n important addressing scheme which TCP defines is the port. Ports separate same P clients to initiate contact, a pecific port can be established from where communications will originate. These efore transmitting data. Information is sent with the assumption that the recipient will be TP), lost data indicating the current time would be invalid methods getLocalHost, getByName, or getAllByName to create a new InetAddress instance. Transmission Control Protocol (TCP) Most Internet applications use TCP to implement rec Reliable. When TCP segments, the smallest unit of TCP transmissions, are lost or corrupted, the TCP implementation will detect this and retransmit necessary segments. Connectionoriented. TCP sets up a connection with a remote system by transmitting control information, often known as a handshake, before beginning a communication. At the end of the connect, a similar closing handshake ends the transmission. Contin an arbitrary number of bytes to be sent and received smoothly; once a connection has been established, TCP segments provide the application layer the appearance of a continuous flow of data. Because of these characteri In you from worrying how the data is broken up or about coding error correction routines. However, TCP requires a significant amount of overhead and perhaps you might wish to code routines that more thin expired. A various TCP communications streams which are running concurrently on the system. For server applications, which wait for TC s concepts come together in a programming abstraction known as sockets. User Datagram Protocol (UDP) UDP is a low-overhead alternative to TCP for host-to-host communications. In contrast to TCP, UDP has the following features: Unreliable. UDP has no mechanism for detecting errors nor retransmitting lost or corrupted information. Connectionless. UDP does not negotiate a connection b listening. Message-oriented. UDP allows applications to send self-contained messages within UDP datagrams, the unit of UDP transmission. The application must package all information within individual datagrams. For some applications, UDP is more appropriate than TCP. For instance, with the Network Time Protocol (N
Basic Java
122 .
by the time it was retransmitted. In a LAN environment, Network File System (NFS) provide reliability at the application layer and thus uses UDP. niform Resource Locator (URL) e. These two portions of can more efficiently As with TCP, UDP provides the addressing scheme of ports, allowing for many applications to simultaneously send and receive datagrams. UDP ports are distinct from TCP ports. For example, one application can respond to UDP port 512 while another unrelated service handles TCP port 512. U While IP addresses uniquely identify systems on the Internet, and ports identify TCP or UDP services on a system, URLs provide a universal identification scheme at the application level. Anyone who has used a Web browser is familiar with seeing URLs, though their complete syntax may not be self-evident. URLs were developed to create a common format of identifying resources on the Web, but they were designed to be general enough so as to encompass applications that predated the Web by decades. Similarly, the URL syntax is flexible enough so as to accommodate future rotocols. p URL Syntax The primary classification of URLs is the scheme, which usually corresponds to an application protocol. Schemes include http, ftp, telnet, and gopher. The rest of the URL syntax is in a format that depends upon the scheminformation are separated by a colon to give us: s cheme-name:scheme-info Thus, while mailto:[email protected] indicates "send mail to user dwb at the machine netspace.org," ftp://[email protected]/ means "open an FTP connection to etspace.org n and log i n as user dwb." nform to a general format that follows the following pattern: chemename://host:port/file-info#internal-reference General URL Format Most URLs used co s Scheme-name is a URL scheme such as HTTP, FTP, or Gopher. Host is the domain name or IP address of the remote system. Port is the port number on which the ervice is listening; since most application protocols define a standard port, unless a nd the colon which delimits it from the host urce requested on the remote system, which often mes is a file. However, the file portion may actually execute a server program and it c file on the system. The internal-reference is identifier of a named anchor within an HTML page. A named anchor llows a link to target a particular location within an HTML page. Usually this is not # s non-standard port is being used, the port a is omitted. File-info is the reso ti usually includes a path to a specifi usually the a used, and this token with the character that delimits it is omitted. Java and URLs Java provides a very powerful and elegant mechanism for creating network client applications allowing you to use relatively few statements to obtain resources from e Internet. The java.netpackage contains the sources of this power, the URL and RLConnection th U
classes. Basic Java 123 . the so re a "relative UR An application can also specifye resourc information to reach thently used within HT frequ or F http://java.sun.com/index.html contained within it the relative URL: FAQ.html it would be a shorthand for: /FAQ.html http://java.sun.com he relativ T name, or port number is missing, the value is inherited from the fully spe not inherited The file component must be specified. The optional anchor is THE URL CLASS lass URL represents a Uniform Resource Locator, a pointer to a "resource" on the can be something as simple as a file or a directory, or it h as a query to a database or to nformation on the types of URLs and their formats can be eb/url-primer.html e previous example of a URL ates that the protocol to use is http (HyperText Transport Protocol) and that the on resides on a host machine named www.ncsa.uiuc.edu. The information t host machine is named demoweb/url-primer.html. The exact meaning of this t. The on the fly. This the information is er to which the TCP is not specified, the example, the default port for http is as: 0/demoweb/urlprimer.html lso known as a "ref" or a "reference". cter "#" followed by more characters. un.com/index.html#chapter1 C World Wide Web. A resource can be a reference to a more complicated object, suc a search engine. More iund at: fo http://www.ncsa.uiuc.edu/demow In general, a URL can be broken into several parts. Th indic informati on tha name on the host machine is both protocol dependent and host dependen information normally resides in a file, but it could be generated component of the URL is called the file c omponent, even thoughnot necessarily in a file. A URL can optionally specify a "port", which is the port numbconnection is made on the remote host machine. If the port default port for the protocol is used instead. For 80. An alternative port could be specified http://www.ncsa.uiuc.edu:808 A URL may have appended to it an "anchor", anchor is indicated by the sharp sign chara The a For example, http://java.s L. Rather, it indicates that after the specifically interested in that part of cument that has the tag chapter1 attached to it. The meaning of a tag is urce specific. L", which contains
only enough e relative to another URL. Relative URLs are ML pages. example, if the contents of the URL: e URL need not specify all the components of a URL. If the protocol, host cified URL. . This anchor is not technically part of the URied resource is retrieved, the application is specifdo
Basic Java
124 .
Example for URL GetURLApp.java import java.net.URL; import java.net.MalformedURLException; public class GetURLApp { public static void main(String args[]) { !=1) error("Usage: java GetURLApp URL"); lformedURLException ex) URL"); ion occurred."); void error(String s){ intln(s); to write to the resource referenced by the URL. In eneral, creating a connection to a URL is a multistep process: Manipulate parameters that affect the connection to the remote resource. Interact with the resource; query header fields and contents. import java.io.*; try { if(args.length System.out.println("Fetching URL: "+args[0]); URL url = new URL(args[0]); BufferedReader inStream = new BufferedReader( new InputStreamReader(url.openStream())); String line; { error("Bad } catch (IOException ex) { error("IOExcept } } public stat ic System.out.pr System.exit(1); } } THE URLCONNECTION CLASS The abstract class URLConnection is the superclass of all classes that represent a communications link between the application and a URL. Instances of this class can be used both to read from and g openConnection() connect() while ((line = inStream.readLine())!= null) { System.out.println(line); } inStream.close(); } catch (Ma
Basic Java
125 .
1. The connection object is created by invoking the openConnection method on a . The setup parameters and general request properties are manipulated. the following methods: setAllowUserInteraction setDoInput e lt ction and UseCaches parameters can be set usi th seCaches. Default val t using the set fa n he s are accessed frequently. The methods: nte g Conte gth Conte Date Expir LastM ntType method. at: URL. 2 3. The actual connection to the remote object is made, using the connect method. 4. The remote object becomes available. The header fields and the contents of the remote object can be accessed. The setup parameters are modified using setDoOutput setIfModifiedSince setUseCaches and the general request properties are modified using the method: * setRequestProperty D fau values for the AllowUserIntera ng e methods setDefaultAllowUserInteraction and setDefaultUperties can be se uesfor general request pro DeultRequestProperty method. Each of the above set methods has a corresponding get method to retrieve the value of the parameter or general request property. The specific parameters and general request properties that are applicable are protocol specific. The following methods are used to access the header fields and the contents after the connection is made to the remote object: * getContent getHeaderField * * getInputStream getOutputStream *C ertai* getCo ader fieldntEncodin * get * get * get * get * get ation odified ntLen ntType
provide convenient access to these fields. The getContentType method is used by the getContent method to determine the type of the remote object; subclasses may find it convenient to override the getConte In the common case, all of the pre-connection parameters and general request properties can be ignored: the pre-connection parameters and request properties default to sensible values. For most clients of this interface, there are only two interesting methods: getInputStream and getObject, which are mirrored in the URL class by convenience methods. More information on the request properties and header fields of an http connection an be found c http://www.w3.org/hypertext/WWW/Protocols/HTTP1.0/draft-ietf-http-spec.html
Basic Java
126 .
TCP Socket Basics at the University of California at Berkeley as a tool rogramming. Originally part of UNIX operating ystems, the concept of sockets has been incorporated into a wide variety of hat is a Socket? munications link over the network with another tilizes the TCP protocol, inheriting the ces of information are needed to create a ient-server applications: A centralized service waits for arious remote machines to request specific resources, handling each request as it ients to know how to communicate with the server, standard pplication protocols are assigned well-known ports. On UNIX operating systems, ly be bound by applications with superuser (for example, Sockets were originally developedto easily accomplish network p s operating environments, including Java. W socket is a handle to a com A application. A TCP socket is one that uehavior of that transport protocol. Four pie b TCP socket: The local system's IP address The TCP port number which the local application is using The remote system's IP address The TCP port number to which the remote application is responding Sockets are often used in cl v arrives. In order for cl a ports below 1024 can on root) privileges, and thus for control, these well-known ports lie within this range, by orts are shown in the following table. convention. Some well known p Well-known TCP ports and services Port Service 21 FTP 23 Telnet 25 SMTP (Internet Mail Transfer) Finger 79 80 HTTP For many application protocols, you can merely usert and then manually emulate a clie the Telnet application to connect nt. This may help you understand communications work. , a port to establish a socket connection. such a port num are usually run by ports are allocated from ated to other operating en a dynamically-allocated port rt on the same machine uely identifies a communications link. Realize that a lients on the same port, since the clients will be on to the service po client-server how Client applications must also obtain, or bind Because the client initiates the communication with the server, ber could conveniently be assigned at runtime. Client applications normal, unprivileged users on UNIX systems, and thus these the range above 1024. This convention has held when migr systems, and client applications are ge nerally givabove 1024. Because no two applications can bind the same po
Basic Java
127 .
different systems and/or different ports; the uniqueness of the link's characteristics P SOCKET CLASSES of classes, which allow you to create socket-based network pplications. The two classes you use include java.net.Socket are preserved. TC JAVA Java has a number a and java.net.ServerSocket. THE SERVERSOCKET CLASS public class ServerSocket extends Object This class implements server sockets. A server socket waits for requests to come in ver the network. It performs some operation based on that request, and then lt to the requester. he actual work of the server socket is performed by an instance of the SocketImpl e the socket factory that creates the socket e itself to create sockets appropriate to the local firewall. .Date; ("server started"); end = new edOutputStream(socket.getOutputStream()); String date = (new Date()).toString(); byte data[] = new byte[date.length()]; data = date.getBytes(); data.length); o possibly returns a resu T class. An application can chang implementation to configur Example for ServerSocket ServerExample.java import java.io.*; import java.net.*; import java.u til pub lic class ServerExample { public static void main(String args[]) { ServerSocket server = null; Socket socket = null; BufferedOutputStream send = nu ll; try { server = new ServerSocket(3000); System.out.println while(true) { socket = server.accept(); s Buffer send.write(data,0, send.flush(); System.out.println("data socket.close(); } } flushed"); send.close();
Basic Java
128 .
catch(Exception err) { System.out.println("Exception in transferring data to client"); } } xample for Socket ientExample <server IP ddress>"); socket = new Socket(InetAddress.getByName(ser_address),3000); rec System.out.println("socket created"); byt d rec v Str g System.out.println("Date from server : "+date); receive.close(); socket.close(); n err){ verview of UDP Messaging rly suited to UDP. UDP requires much less overhead, but the burden of } THE SOCKET CLASS This class implements client sockets (also called just "sockets"). A socket is an endpoint for communication between two machines. The actual work of the socket is performed by an instance of the SocketImpl class. An application, by changing the socket factory that creates the socket implementation, can configure itself to create sockets appropriate to the local firewall. E import java.io.*; import java.net.*; public class ClientExample { public static void main(String args[]) { Socket socket = null; BufferedInputStream receive = null; if(args.length == 0){ System.out.println("Usage : java Cl a System.exit(0); } String ser_address = args[0]; try { eive = new BufferedInputStream(socket.getInputStream()); e ata[] = new byte[100]; eie.read(data,0,data.length); in date = new String(data); } catch(Exceptio System.out.println("Exception in accessing file"); } } } O Programming with UDP has significant ramifications. Understanding these factors will inform your network programming. UDP is a good choice for applications in which communications can be separated into discrete messages, where a single query from a client invokes a single response from a server. Time-dependent data is particula
Basic Java
129 .
engineering any necessary reliability into the system is your responsibility. For responses to their queriesperfectly possible and gitimate with UDPyou might want to program the clients to retransmit the request mative message indicating communication difficulties. essageoriented. A common ith postcards. A dialog with all messages that fit within a small packet of a rn ur r message could have been lost en route, the recipients lost, or the recipient might be ignoring your message. een network programs are referred to as store an array of bytes. A receiving your message, possibly sending a ming abstraction. However, UDP sockets are very different from TCP e analogy, UDP sockets are much like creating a mailbox. A dress on m the message is intended. You place the postcard , you could potentially wait forever until one arrives in your read the postcard. Meta-information appears on l tasks: Creating an appropriately addressed datagram to send. up a socket to send and receive datagrams for a particular tion. ket for transmission. from a socket. instance, if clients never receive le or perhaps display an infor UDP Socket Characteristics UDP is described as unreliable, connectionless, and mgy that elucidates UDP is that of communicating w analo UDP must be quanticized into sm, although some packets can hold more data than others. When you specific size send out a message, you can never be certain that you will receive a retumessage. Unless you do receive a return message, you have no idea if yo message was receivedyoucould have been confirmation The postcards you will be exchanging betw datagrams. Within a datagram, you can application can extract this array and decode gram response. As with TCP, you will program in UDP using the socket return data program sockets. Extending thmailbox is identified by your address, but you don't construct a new one for each person to whom you will be sending a message. Instead, you place an ad the postcard that indicates to who in the mailbox and it is (eventually) sent on its way. When receiving a message mailbox . Once one does, you can the postcard that identifies the sender through the return address. As the previous analogies suggest, UDP programming involves the following genera Settingapplica Inserting datagrams into a soc Waiting to receive datagrams Decoding a datagram to extract the message, its recipient, and other meta-information. Java UDP Classes The java.net package has the tools that are nece
ssary to perform UDP communications. For working with datagrams, Java provides the DatagramPacket and DatagramSocket classes. When receiving a UDP datagram, you also use the DatagramPacket class to read the data, sender, and meta-information. THE DATAGRAMPACKET CLASS This class represents a datagram packet. Datagram packets are used to implement a connectionless packet delivery service. Each message is routed from one machine to another based solely on information contained within that packet. Multiple packets sent from one machine to another might be routed differently, and might arrive in any order.
Basic Java
130 .
Example for DatagramPacket import java.net.*; import java.io.*; public class DatagramClient { public static void main(String args[]) { ngth == 0) t dgp = null; ))); a datagram socket is individually ddressed and routed. Multiple packets sent from one machine to another may be if(args.le { System.out.println("Usage : java DatagramClient <server address>"); System.exit(0); } String address = args[0]; DatagramPacke DatagramSocket dgs = null; byte receive[] = new byte[50]; try { dgs = new DatagramSocket(5000,InetAddress.getByName(address)); dgp = new DatagramPacket(receive,receive.length); dgs.receive(dgp); System.out.println("data received : "+(new tring(receive S dgs.close(); } catch(Exception err) { System.out.println("Exception in client"); } } } THE DATAGRAMSOCKET CLASS This class represents a socket for sending and receiving datagram packets. A datagram socket is the sending or receiving point for a connectionless packet delivery service. Each packet sent or received on a routed differently, and may arrive in any order.
Basic Java
131 .
BC JD
com terms of the ODBC standard C API. What Is JDBC ? JDBCTM is a JavaTM API for executing SQL s tatements. (As a point of intis a trademarked name and is not an acronym; nevertheless, JDBC is of as standing for "Javinterfaces written in th e Java programming langfor tool/database developers a pure Java API. using U Sybase database, another program to access an Oracle datab to access an Informix database, and so on. One can write a single program using the JDBC API, and the program will be able to send SQL statements to the appropriate database. And, with an application written in the Java programming language, one also doesn't have to worry about writing different applications to run on different platforms. The combination of Java and JDBC lets a programmer write it once and run it anywhere. Jav a, being robust, secure, easy to use, easy to understand, and automatically adable on a network, is an excellent language basis for database applications. s needed is a way for Java applications to talk to a variety of different ses. JDBC is the mechanism for doing this. xtends what can be done in Java. For example, with Java and the JDBC API, ssible to publish a web page containing an applet that uses information d from a remote ployees (even if they are using a conglomeration of Windows, Macintosh, and achines) to one or more internal databases via an intranet. With more and programmers using the Java programming language, the need for easy se access from Java is continuing to grow. anagers like the combination of Java and JDBC because it makes inating information easy and economical. Businesses can continue to use stalled databases and access information easily d
TM
Installation and version control are greatly simplified. A programmer can write an application or an update once, put it on the server, and everybody has access to the latest version. And for businesses selling information services, Java and JDBC offer a better way of getting out information updates to external customers.
Basic Java
132 .
What Does JDBC Do? do three things: mt = con.createStatement(); = stmt.executeQuery("SELECT a, b, c FROM Table1"); w Str floa c"); JDBC JDBC is a "low-level" interface, which means com databa build h a m into higher- 3. va In this "object/relational" tion might present a menu of database tasks from which to choose. After a task is selected, the application presents prompts and blanks for filling in information needed to carry out the selected task. With the requested input typed in, the application then automatically invokes the necessary SQL commands. With the help of such an application, users can perform database tasks even when they have little or no knowledge of SQL syntax. Simply put, JDBC makes it possible to establish a connection with a database send SQL statements process the results. The following code fragment gives a basic example of these three steps: Connection con = DriverManager.getConnection ( "jdbc:odbc:wombat", "login", "password"); Statement st ResultSet rs hile (rs.next()) { int x = getInt("a"); ing s = getString("b"); t f = getFloat(" } Is a Low-level API and a Base for Higher-level APIs that it is used to invoke (or "call") SQL mands directly. It works very well in this capacity and is easier to use than other se connectivity APIs, but it was designed also to be a base upon which to igher-level interfaces and tools. A higher-level interface is "userfriendly," using understandable or more con orevenient API that is translated behind the scenes a low-level interface such as JDBC. At the time of this writing, two kinds of level APIs are under development on top of JDBC: an embedded SQL for Java. At least one vendor plans to build this. DBMSs implement SQL, a language designed specifically for use with databases. JDBC requires that the SQL statements be passed as Strings to Ja methods. An embedded SQL preprocessor allows a programmer to instead mix SQL statements directly with Java: for example, a Java variable can be used in a SQL statement to receive or provide SQL values. The embedded SQL preprocessor then translates this Java/SQL mix into Java with JDBC calls. 4. a direct mapping of relational database tables to Java classes. JavaSoft and others have announced plans to implement this. mapping, each row of the table becomes an instance of that class, and each column value corresponds to an attribute of that instance. Programmers can then operate directly on Java objects; the required SQL calls to fetch and store data are automatically generated "beneath the covers." More sophisticated mappings are also provided, for example, where rows of multiple tables are combined in a Java class. As interest in JDBC has grown, more developers have been working on JDBC-based tools to make building programs easier, as well. Programmers have also been writing applications that make accessing a database easier for the end user. For example, an applica
Basic Java
133 .
JDBC versus ODBC and other APIs t this point, Microsoft's ODBC (Open DataBase Connectivity) API is probably the ers Calls from Java to native C code have a number of drawbacks in the security, implementation, robustness, and automatic portability of applications. 2. A literal translation of the ODBC C API into a Java API would not be desirable. For example, Java has no pointers, and ODBC makes copious use of them, including the notoriously rrorprone generic pointer "void *". You can think of JDBC as ODBC transla d interface that is natural for Java programmers. 3. ODBC is hard to learn. It mixes simple and advanced features together, and it has complex options even for simple queries. JDBC, on the other hand, was designed to keep simple things simple while allowing more advanced capabilities where required. 4. A Java API like JDBC is needed in order to enable a "pure Java" solution. When ODBC is used, the ODBC driver manager and drivers must be urse, it is easy to use. ore recently, Microsoft has introduced new APIs beyond ODBC: RDO, ADO, and LE DB. These designs move in the same direction as JDBC in many ways, that is, being an object-oriented database interface based on classes that can be plemented on ODBC. However, we did not see compelling functionality in any of ese interfaces to make them an alternative basis to ODBC, especially with the DBC driver market well-established. Mostly they represent a thin veneer on ODBC. his is not to say that JDBC does not need to evolve from the initial release; owever, we feel that most new functionality belongs in higher- level APIs such as e object/relational mappings and embedded SQL mentioned in the previous ection. A most widely used programming interface for accessing relational databases. It off the ability to connect to almost all databases on almost all platforms. So why not just use ODBC from Java? The answer is that you can use ODBC from Java, but this is best done with the help of JDBC in the form of the JDBC-ODBC Bridge, which we will cover shortly. The question now becomes, "Why do you need JDBC?" There are several answers to this question: 1. ODBC is not appropriate for direct use from Java because it uses a C interface. e ted into an object-oriente manually installed on every client machine. When the JDBC driver is written completely in Java, however, JDBC code is automatically installable, portable, and secure on all Java platforms from network computers to mainframes. In summary, the JDBC API is a natural Java interface to the basic SQL abstractions and concepts. It builds on ODBC rather than starting from scratch, so programmers familiar with ODBC will find it very easy to learn JDBC. JDBC retains the basic design features of ODBC; in fact, both interfaces are based on the X/Open SQL CLI (Call Level Interface). The big difference is that JDBC builds on and reinforces the tyle and virtues of Java, and, of co s M O in im th O T h th s
Basic Java
134 .
Two-tier and Three-tier Models The JDBC API supports both two-tier and three-tier models for database access. In the two-tier model, a Java applet or application talks directly to the database. This requires a JDBC driver that can communicate with the particular database anagement system being accessed. A user's SQL stateme mdnts are delivered to the atabase, and the results of those statements are sent back to the user. The ated on another machine to which the user is connected via a middle tier, which then sends them to the user. MIS he middle tier makes it Finally, in many cases the three-tier architecture can rovide performance advantages. database may be loc network. This is referred to as a client/server configuration, with the user's machine as the client, and the machine housing the database as the server. The network can be an intranet, which, for example, connects employees within a corporation, or it can be the Internet. Java Application JDBC DBMS Client Machine DBMS Proprietary Protocol In the three-tier model, commands are sent to a "middle tier" of services, which then send SQL statements to the database. The database processes the SQL statements and sends the results back to theirectors find the three-tier model very attractive because t d possible to maintain control over access and the kinds of updates that can be made to corporate data. Another advantage is that when there is a middle tier, the user can employ an easy-to-use higher-level API which is translated by the middle tier into the appropriate low-level calls. Database Server p Java Applet or HTML Browser Application Server (Java) JDBC DBMS
Basic Java
135 .
Until now the middle tier has typically been written in languages such as C or C++, which offer fast performance. However, with the introduction of optimizing compilers at translate Java bytecode into efficient machine-specific code, it is becoming he middle tier in Java. This is a big plus, making it possible to SQ Str u ) is the standard language for accessing relational SQL syntax or semantics for more dvanced functionality. For example, not all databases support stored procedures or e meantime, however, the JDBC API must support SQL as it is. t, an application query need not even be SQL, or it may be a pecialized derivative of SQL designed for specific DBMSs (for document or image C-sty The es commo and for For co ird way. It pro Databa capabi Bec databa for any standa design refers 1992. E ascerta the JDB The implem conform in the function not currently branding vendor implementations, but this compliance definition th practical to implement ttake advantage of Java 's robustness, multithreading, and security features. JDBC is important to allow database access from a Java middle tier. L Conformance uctred Query Language (SQL databases. One area of difficulty is that although most DBMSs (DataBase Management Systems) use a standard form of SQL for basic functionality, they do not conform to the more recently-defined standard a outer joins, and those that do are not consistent with each other. It is hoped that the portion of SQL that is truly standard will expand to include more and more functionality. In th One way the JDBC API deals with this problem is to allow any query string to be passed through to an underlying DBMS driver. This means that an application is free to use as much SQL functionality as desired, but it runs the risk of receiving an error on some DBMSs. In fac s queries, for example). A second way JDBC deals with problems of SQL conformance is to provide ODB le escape clauses. cape syntax provides a standard JDBC syntax for several of the more n areas of SQL divergence. For example, there are escapes for date literals stored procedure calls. mplex applications, JDBC deals with SQL conformance in a th vides descriptive information about the DBMS by means of the seMetaData interface so that applications can adapt to the requirements and lities of each DBMS. ause the JDBC API will be used as a base API for developing higher-level se access tools and APIs, it also has to address the problem of conformance thing built on it. The designation "JDBC COMPLIANT " was created to set a rd level of JDBC functionality on which users can rely. In order to use this ation, a driver must support at least ANSI SQL-2 Entry Level. (ANSI SQL-2 to the standards adopted by the American National Standards Institute in ntry Level refers to a specific list of SQL capabilities.) Driver developers can in that their drivers meet these standards by using the test suite available with C API. "JDBC COMPLIANT " designation indicates that a vendor's JDBC entation has passed the conformance tests provided by JavaSoft. These ance tests check for the existence of all of the classes and methods defined JDBC API, and check as much as possible that
TM TM
the SQL Entry Level ality is available. Such tests are not exhaustive, of course, and JavaSoft is
Basic Java
136 .
provides some degree of confidence in a JDBC implementation. With wider and wider acceptance of the JDBC API by database vendors, connectivity vendors, Internet service vendors, and application writers, JDBC is quickly becoming the standard for Java database access. JavaSoft Framework JavaSoft provides three JDBC product components as part of the Jit (JDK): ava Development manager, t suite, and ridge. er is the backbone of DBC architecture. simple; its primary function is nnect Java get out of the way provides some confidence that JDBC drivers will run your pass the JDBC driver test suite can be designated JDBC as a way to get JDBC off the ground quickly, and long term will provide way to access some of the less popular DBMSs if JDBC drivers are not bridge product provides JDBC access via ODBC drivers. Note that ODBC binary code, and tabase client code, must be loaded on each client machine slated to a DBMS protocol by a ng DBC calls into the network protcol used by DBMSs directly. This allows a direct call from the client machine to the DBMS server and is a practical solution for Intranet access. Since many of these protocols are proprietary, the database vendors themselves will be the primary source, and several database vendors have these in progress. K the JDBC driver the JDBC driver tes the JDBC-ODBC bThe JDBC driver manag quite small and correct JDBC driver and then the J to co It actually is applications to the .
The JDBC driver test suiteprogram. Only drivers that COMPLIANT . The JDBC-ODBC bridge allows ODBC drivers to be used as JDBC drivers. It was implemented a implemented for them. JDBC Driver Types The JDBC drivers that we are aware of at this time fit into one of four categories: 1. JDBC-ODBC bridge plus ODBC driver: The JavaSoft
in many cases da that uses this driver. As a result, this kind of driver is most appropriate on a corporate network where client installations are not a major problem, or for application server code written in Java in a three-tier architecture. 2. Native-API partly-Java driver: This kind of driver converts JDBC calls into calls on the client API for Oracle, Sybase, Informix, DB2, or other DBMS. Note that, like the bridge driver, this style of driver requires that some binary code be loaded on each client machine. 3. JDBC-Net pure Java driver: This driver translates JDBC calls into a DBMSindependent net protocol which is then tran server. This net server middleware is able to connect its pure Java clients to many different databases. The specific protocol used depends on the vendor. In general, this is the most flexible JDBC alternative. It is likely that all vendors of this solution will provide products suitable for Intranet use. In order for these products to also support Internet access, they must
TM
handle the additional requirements for security, access through firewalls, and so on, that the Web imposes. Several vendors are adding JDBC drivers to their existi database middleware produc ts. 4. Native-protocol pure Java driver: This kind of driver converts J
Basic Java
137 .
Eventually, we expect access databases fromthat driver categories 3 and 4 will be the preferred way to JDBC. Driver categories 1 and 2 are interim solutions where irect pure Java drivers are not yet available. There are possible variations on ll the advantages of he following chart shows the four categories and their properties: d categories 1 and 2 (not shown in the table below) that require a connector, but these are generally less desirable solutions. Categories 3 and 4 offer a Java, including automatic installation (for example, downloading the JDBC driver with an applet that uses it). T DRIVER CATEGORY ALL JAVA? NET PROTOCOL 1 JDBC-OCBC Bridge No Direct 2 Native API as basis No Direct JDBC-Net Yes Requires Connector 3 4 Native protocol as basis Yes Direct Obtaining JDBC Drivers The first vendors with Category 3 drivers available were SCO, Open Horizon, Visigenic, and WebLogic. JavaSoft and Intersolv, a leading database connectivity vendor, worked together to produce the JDBC-ODBC Bridge and the JDBC Driver Test Suite. C onnection A Connection object represents a connection with a database. A connection session includes the SQL statements that are executed and the results that are returned over at conn th ection. A single application can have one or more connections with a single ith many different databases. way to establish a connection with a database is to call the method riverManager.getConnection. This method takes a string containing a URL. The ndle opening a connection. database, or it can have connections w Opening a Connection The standard D DriverManager class, referred to as the JDBC management layer, attempts to locate a driver than can connect to the database represented by that URL. The DriverManager class maintains a list of registered Driver classes, and when the method getConnection is called, it checks with each driver in the list until it finds one that can connect to the database specified in the URL. The Driver method connect uses this URL to actually establish the connection. A user can bypass the JDBC management layer and call Driver methods directly. This could be useful in the rare case that two drivers can connect to a database and the user wants to explicitly select a particular driver. Normally, however, it is much asier to just let the DriverManager class ha e The following code exemplifies opening a connection to a database located at the URL "jdbc:odbc:wombat" with a user ID of "oboy" and "12Java" as the password : String url = "jdbc:odbc:wombat"; Connection con = DriverManager.getConnection(url, "oboy", "12Java");
Basic Java
138 .
URLs in General Use Since URLs often cause some confusion, we will first give a brief explanation of URLs in general and then go on to a discussion of JDBC URLs. URL (Uniform Resource Locator) gives information for locating a resource on the s information, and it is alw specifies "file tran protoco the Inte ftp://jav http://java.sun.com/products/JDK/CurrentRelease file:/hom orial.html The rest of a URL, everything after the first colon, gives information about where the data so For the http, the rest of the URL identifies the host and may optiona L for the JavaSo http://w A Internet. It can be thought of as an address. The first part of a URL specifies the protocol used to acces ays followed by a colon. Some common protocols are "ftp", which sfer protocol," and "http," which specifies "hypertext transfer protocol." If the l is "file," it indicates that the resource is in a local file system rather than on rnet. asoft.com/docs/JDK-1_apidocs.zip e/haroldw/docs/tut urce is located. If the protocol is file, the rest of the URL is the path to a file. protocols ftp and lly give a path to a more specific site. For example, below is the URft home page. This URL identifies only the host: ww.javasoft.com By nav ge, one can go to many other pages, one of which is the JDBC home page. The URL for the JDBC home page is more specific and looks like this: http://w JDB U A JDBC will rec actually Users d supplie conven URLs. ince J kinds of drivers, the conventions are of necessity very flexible. First, they allow different drivers to use different schemes for naming values er writers to encode all necessary connection formation within them. This makes it possible, for example, for an applet that wants talk to a given database to open the database connection without requiring the inistration chores. nt igating from this home pa ww.javasoft.com/products/jdbc C RLs URL provides a way of identifying a database so that the appropriate driver ognize it and establish a connection with it. Driver writers are the ones who determine what the JDBC URL that identifies their particular driver will be. o not need to worry about how to form a JDBC URL; they simply use the URL d with the drivers they are using. JDBC's role is to recommend some tions for driver writers to follow in structuring their JDBC SDBC URLs are used with various databases. The odbc subprotocol, for example, lets the URL contain attribute (but does not require them). Second, JDBC URLs allow driv into user to do any system adm Third, JDBC URLs allow a level of indirection. This means that the JDBC URL may refer to a logical host or database name that is dynamically translated to the actual name by a network naming system. This allows system administrators to avoid specifying particular hosts as part of the JDBC name. There are a number of differe
Basic Java
139 .
network name services (such as DNS, NIS, and DCE), and there is no restriction be used. ree parts, which are jdbc:<subprotocol>:<subname> rotocol is "odbc", and the subname "fred" is a local ODBC data source. network name service (so that the database rotocol, and it can have a subsubname with any jdb The "o The su ODBC-of attrib specified after the subname (the data source name). The full bute-value>]* about which ones can The standard syntax for JDBC URLs is shown below. It has th separated by colons: The three parts of a JDBC URL are broken down as follows: 5. jdbc-the protocol. The protocol in a JDBC URL is always jdbc. 6. <subprotocol>-the name of the driver or the name of a database connectivity mechanism, which may be supported by one or more drivers. A prominent example of a subprotocol name is "odbc", which has been reserved for URLs that specify ODBC-style data source names. For example, to access a database through a JDBC-ODBC bridge, one might use a URL such as the following: jdbc:odbc:fred In this example, the subp If one wants to use a name in the JDBC URL does not have to be its actual name), the naming service can be the subprotocol. So, for example, one might have a URL like: jdbc:dcenaming:accounts-payable In this example, the URL specifies that the local DCE naming service should resolve the database name "accounts-payable" into a more specific name that can be used to connect to the real database. 7. <subname>-a way to identify the database. The subname can vary, depending on the subp internal syntax the driver writer chooses. The point of a subname is to give enough information to locate the database. In the previous example, "fred" is enough because ODBC provides the remainder of the information. A database on a remote server requires more information, however. If the database is to be accessed over the Internet, for example, the network address should be included in the JDBC URL as part of the subname and should follow the standard URL naming convention of //hostname:port/subsubname Supposing that "dbnet" is a protocol for connecting to a host on the Internet, a JDBC URL might look like this: c:dbnet://wombat:356/fred dbc" Subprotocol bprotocol odbc is a special case. It has been reserved for URLs that specify style data source names and has the special feature of allowing any number ute values to be syntax for the odbc subprotocol is: jdbc:odbc:<data-source-name>[;<attribute-name>=<attri
Basic Java
the subprotocol in a JDBC ss presents this name to its list of registered drivers e is reserved should recognize it and establish a connec n s. For example, odbc is reserved for the JDBCDBC Bridge. If there were, for another example, a Miracle Corporation, it might want to register "miracle" as the subprotocol for the JDBC driver that connects to its so that no one else would use that name. rocedure call to a DBMS that does not support . aredStatement- -created by the method prepareStatement. A executed. Instances of PreparedStatement extend Statement and therefore include Statement methods. A PreparedStatement object has the potential to be more efficient than a en pre-compiled and stored for future use. s all of the following are valid jdbc:odb c:obc:wombat c:wombat;CacheSize=20;ExtensionCase=LOW jdbc:odbc:qeora;UID=kgh;PWD=fooey erig Subprotocols A driver developer can reserve a nURL. When the DriverManager cla , th driver for which this nametio to the database it identifie O Miracle DBMS JavaSoft is acting as an informal registry for JDBC subprotocol names. To register a subprotocol name, send email to: [email protected] Sending SQL Statements Once a connection is established, it is used to pass SQL statements to its underlying database. JDBC does not put any restrictions on the kinds of SQL statements that can be sent; this provides a great deal of flexibility, allowing the use of database-specific statements or even non-SQL statements. It requires, however, that the user be responsible for making sure that the underlying database can process the SQL statements being sent and suffer the consequences if it cannot. For example, an pplication that tries to send a stored p a stored procedures will be unsuccessful and generate an exception. JDBC requires that a driver provide at least ANSI SQL-2 Entry Level capabilities in order to be designated JDBC COMPLIANT . This means that users can count on at least this tandard level of functionality s JDBC provides three classes for sending SQL statements to the database, and three methods in the Connection interface create instances of these classes. These classes and the methods which create them are listed below: 5. Statement- -created by the method createStatement. A Statement object is used for sending simple SQL statements. 6. Prep PreparedStatement object is used for SQL statements that take one or more parameters as input arguments (IN parameters). PreparedStatement has a group of methods which set the value of IN parameters, which are sent to the database when the statement is Statement object because it has be 7. CallableStatement- -created by the method prepareCall. CallableStatement objects are used to execute SQL stored procedures- -a group of SQL statements that is called by name, much like invoking a function. A CallableStatement object inherits methods for handling IN parameters from PreparedStatement; it adds methods for handling OUT and INOUT parameters. The
TM
following list gives a quick way to determine which Connection method is appropriate for creating different types of SQL statements:
Basic Java
141 .
createStatement method is used for simple SQL statements (no parameters) prepareStatement method is used for SQL statements with one or more IN parameters simple SQL statements that are executed frequently prepareCall method is used for call to stored procedures Transactions A transaction consists of one or more statements that have been executed, completed, and then either committed or rolled back. When the method commit or rollback is called, the current transaction ends and another one begins. A new connection is in autocommit mode by default, meaning that when a statement is completed, the method commit will be called on that statement automatically. In this case, since each statement is committed individually, a transaction consists of only one statement. If auto-commit mode has been disabled, a transaction will not rminate until the method commit or rollback is called explicitly, so it will include all e statements that have been executed since the last invocation of the commit or In this second case, all the statements in the transaction are ed back as a group. t one change to take effect unless another one does act, a JDBC-compliant driver must upport transactions. DatabaseMetaData supplies information describing the level of a value and a second transaction rea be allo invalid DBMS to teth rollback method.ommitted or roll c The method commit makes permanent any changes an SQL statement makes to a database, and it also releases any locks held by the transaction. The method rollback will discard those changes. ometimes a user doesn't wan Sa lso. This can be accomplished by disabling auto-commit and grouping both updates into one transaction. If both updates are successful, then the commit method is called, making the effects of both updates permanent; if one fails or both fail, then the rollback method is called, restoring the values that existed before the updates were executed. Most JDBC drivers will support transactions. In f s transaction support a DBMS provides. Transaction Isolation Levels If a DBMS supports transaction processing, it will have some way of managing potential conflicts that can arise when two transactions are operating on a database at the same time. A user can specify a transaction isolation level to indicate what level of care the DBMS should exercise in resolving potential conflicts. For example, what happens when one transaction changes ds that value before the change has been committed or rolled back? Should that wed, given that the changed value read by the second transaction will be if the first transaction is rolled back? A JDBC user can instruct the
Basic Java
142 . allow a value to be read before it has been committed ("dirty reads") with the
followin con. The hig e more care is taken to avoid conflicts. The transac transac to the slower concur with the el epends on the apabilities of the underlying DBMS. onnection object is created, its transaction isolation level depends on e driver, but normally it is the default for the underlying database. A user may call commended, for it will trigger an mediate call to the method commit, causing any changes up to that point to be riverManager iver. In addition, e DriverManager class attends to things like driver login time limits and the printing connect, but in most cases it is better to let the DriverManager class anage the details of establishing a connection. gisters it with the DriverManager class when it is loaded. Thus, a user would not citly loads the driver class. recommended. The following code loads the class acme.db.Driver: g code, where con is the current connection: setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED); her the transaction isolation level, th Connection interface defines five levels, with the lowest specifying that tions are not supported at all and the highest specifying that while one tion is operating on a database, no other transactions may make any changes data read by that transaction. Typically, the higher the level of isolation, the the application executes (due to increased locking overhead and decreased rency between users). The developer must balance the need for performance need for data consistency when making a decision about what isolation lev to use. Of course, the level that can actually be supported d c When a new C th the method setIsolationLevel to change the transaction isolation level, and the new level will be in effect for the rest of the connection session. To change the transaction isolation level for just one transaction, one needs to set it before the transaction begins and reset it after the transaction terminates. Changing the transaction isolation level during a transaction is not re im made permanent. D The DriverManager class is the management layer of JDBC, working between the user and the drivers. It keeps track of the drivers that are available and handles establishing a connection between a database and the appropriate dr th of log and tracing messages. For simple applications, the only method in this class that a general programmer needs to use directly is DriverManager.getConnection. As its name implies, this method establishes a connection to a database. JDBC allows the user to call the DriverManager methods getDriver, getDrivers, and registerDriver as well as the Driver method m Keeping Track of Available Drivers The DriverManager class maintains a list of Driver classes that have registered themselves by calling the method DriverManager.registerDriver. All Driver classes should be written with a static section that creates an instance of the class and then re normally call DriverManager.registerDriver directly; it should be called automatically by a driver when it is loaded. A Driver class is loaded, and therefore automatically registered with the
DriverManager, in two ways: 8. By calling the method Class.forName. This expliSince it does not depend on any external setup, this way of loading a driver is
Basic Java
143 .
Class.forName("acme.db.Driver"); If acme.db.Driver has been written so that loading it causes an instance to be created and also calls DriverManager.registerDriver with that instance as the parameter (as it should do), then it is in the DriverManager's list of drivers and available for creating a connection. he DriverManager class is intialized, it looks for the system property jdbc.drivers, and if the user has entered one or more drivers, the ~/.hotjava/properties ombat.sql.Driver:bad.test.ourDriver; he first call to a DriverManager method will automatically cause these driver classes be loaded. a database. When a r.getConnection ver in turn to see if it can establish a is capable of onnecting to a given URL. For example, when connecting to a given remote might be possible to use a JDBC-ODBC bridge driver, a JDBC-toby the database vendor. In such c.drivers are always registered first.) It will skip 9. By adding the driver to the java.lang.System property jdbc.drivers. This is a list of driver classnames, separated by colons, that the DriverManager class loads. When t DriverManager class attempts to load them. The following code illustrates how a programmer might enter three driver classes in (HotJava loads these into the system properties list on startup): jdbc.drivers=foo.bah.Driver:w Tto Note that this second way of loading drivers requires a preset environment that is persistent. If there is any doubt about that being the case, it is safer to call the method Class.forName to explicitly load each driver. This is also the method to use to bring in a particular driver since once the DriverManager class has been initialized, it will never recheck the jdbc.drivers property list. In both of the cases listed above, it is the responsibility of the newly-loaded Driver class to register itself by calling DriverManager.registerDriver. As mentioned above, this should be done automatically when the class is loaded. For security reasons, the JDBC management layer will keep track of which class loader provided which driver. Then when the DriverManager class is opening a connection, it will use only drivers that come from the local file system or from the ame class loader as the code issuing the request for a connection. s Establishing a Connection Once the Driver classes have been loaded and registered with the DriverManager class, they are available for establishing a connection with request for a connection is made with a call to the DriverManage method, the DriverManager tests each dri connection. It may sometimes be the case that more than one JDBC driver cdatabase, it generic-network-protocol driver, or a driver supplied cases, the order in which the drivers are tested is significant because the DriverManager will use the first driver it finds that can successfully connect to the given URL. First the DriverManager tries to use each of the drivers in the order they were gistered. (The drivers listed in jdb re any drivers which are untrusted code, unless they have been loaded from the same source as the code that is trying to open the connection.
Basic Java
144 .
It tests the drivers by calling the method Driver.connect on each one in turn, passing them the URL that the user originally passed to the method DriverManager.getConnection. The first driver that recognizes the URL makes the connection. At first glance this may seem inefficient, but it requires only a few procedure calls and ample of all that is normally needed to set up a onnection with a driver such as a JDBC-ODBC bridge driver: ment object is used to execute a precompiled SQL tatement with or without IN parameters; and a CallableStatement object is used to se stored procedure. h the Connection b, c FROM Table2); Statement objects tatements that produce a single result set, such as SELECT statements. The method executeUpdate is used to execute INSERT, UPDATE, or DELETE statements and also SQL DDL (Data Definition Language) statements like CREATE TABLE and DROP TABLE. The effect of an INSERT, UPDATE, or DELETE string comparisons per connection since it is unlikely that dozens of drivers will be loaded concurrently. The following code is an ex c Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //loads the driver String url = "jdbc:odbc:fred"; DriverManager.getConnection(url, "userID", "passwd"); Statement A Statement object is used to send SQL statements to a database. There are actually three kinds of Statement objects, all of which act as containers for executing SQL statements on a given connection: Statement, PreparedStatement, which inherits from Statement, and CallableStatement, which inherits from PreparedStatement. They are specialized for sending particular types of SQL statements: a Statement object is used to execute a simple SQL statement with no arameters; a PreparedState ps execute a call to a databa The Statement interface provides basic methods for executing statements and retrieving results. The PreparedStatement interface adds methods for dealing with IN parameters; CallableStatement adds methods for dealing with OUT parameters. Creating Statement Objects Once a connection to a particular database is established, that connection can be sed to send SQL statements. A Statement object is created wit u method createStatement, as in the following code fragment: Connection con = DriverManager.getConnection(url, "sunny", ""); Statement stmt = con.createStatement(); The SQL statement that will be sent to the database is supplied as the argument to one of the methods for executing a Statement object: ResultSet rs = stmt.executeQuery("SELECT a, Executing Statements Using The Statement interface provides three different methods for executing SQL statements, executeQuery, executeUpdate, and execute. The one to use is determined by what the SQL statement produces. The method executeQuery is designed for s
Basic Java
145 .
statement is a modification of one or more columns in zero or more rows in a table. pdate is an integer indicating the number of rows that the update count). For statements such as CREATE lt set if there is one open. This means that one needs to complete any rocessing of the current ResultSet object before re-executing a Statement object. t or CallableStatement versions of these methods will cause an xecuteUpdate, a statement is completed when it is executed. In the rare cases The return value of executeUwere affected (referred to as T ABLE or DROP TABLE, which do not operate on rows, the return value of executeUpdate is always zero. The method execute is used to execute statements that return more than one result set, more than one update count, or a combination of the two. Because it is an advanced feature that most programmers will never need, it is explained in its own section later in this overview. All of the methods for executing statements close the calling Statement object's current resu p It should be noted that the PreparedStatement interface, which inherits all of the methods in the Statement interface, has its own versions of the methods executeQuery, executeUpdate and execute. Statement objects do not themselves contain an SQL statement; therefore, one must be provided as the argument to the Statement.execute methods. PreparedStatement objects do not supply an SQL statement as a parameter to these methods because they already contain a precompiled SQL statement. CallableStatement objects inherit the PreparedStatement forms of these methods. Using a query parameter with the PreparedStatemen S QLException to be thrown. Statement Completion When a connection is in auto-commit mode, the statements being executed within it are committed or rolled back when they are completed. A statement is considered complete when it has been executed and all its results have been returned. For the method executeQuery, which returns one result set, the statement is completed when all the rows of the ResultSet object have been retrieved. For the method e where the method execute is called, however, a statement is not complete until all of the result sets or update counts it generated have been retrieved. Some DBMSs treat each statement in a stored procedure as a separate statement; others treat the entire procedure as one compound statement. This difference becomes important when auto-commit is enabled because it affects when the method commit is called. In the first case, each statement is individually committed; in the second, all are committed together. Closing Statement Objects Statement objects will be closed automatically by the Java garbage collector. Nevertheless, it is recommended as good programming practice that they be closed explicitly when they are no longer needed. This frees DBMS resources immediately and helps avoid potential memory problems.
Basic Java
146 .
Using the Method execute The execute method should be used only when it is possible that a statern more than one ResultSet object, more than one update coment may unt, or a ts. These multiple possibilities for re, are possible when one is executing certain stored procedures or ring (that is, unknown to the application might execute a stored procedure then a select, then an update, out of the ordinary, it is no ng. For instance, e returns two result sets. After using the method one must call the method getResultSet to get the nd then the appropriate getXXX methods to retrieve values from it. To e second result set, one needs to call getMoreResults and then getResultSet a ond time. If it is known that a procedure returns two update counts, the method ults and a second call to now what will be returned present a more the result is a ResultSet r the statement executed was a DDL command. The first thing method execute, is to call either getResultSet or d getResultSet is called to get what might be the first of esultSet objects; the method getUpdateCount is called to get what st of two or more update counts. hen the result of an SQL statement is not a result set, the method getResultSet will turn null. This can mean that the result is an update count or that there are no more only way to find out what the null really means in this case is to call the e following is true: e ResultSet object it returned, it is necessary to call the method getMoreResults to see if there is another result set or update count. If getMoreResults returns true, then one needs to again call g ultS ually retrieve the next result set. As already stated above, if getR re one h means that the result is an update count or that there are no more results. Whe reR rns f upda ere are eeds to call the method retu combination of ResultSet objects and update coun results, though ra dynamically executing an unknown SQL st programmer at compile time). For example, a user and that stored procedure could perform an update,ically, someone using a stored procedure will know what then a select, and so on. Typ it returns. Because the method execute handles the cases that are surprise that retrieving its results requires some special handli suppose it is known that a procedurdure, execute to execute the proce first result set a get th sec getUpdateCount is called first, followed by getMoreRes getUpdateCount. Those cases where one does not kion. The method execute returns true if complicated situat object and false if it is a Java int. If it returns an int, that means that the result is eithe an update count or that to do after calling the getUpdateCount. The metho two or more Rbe the fir might Wre results. Themethod get
UpdateCount, which will return an integer. This integer will be the number of rows affected by the calling statement or -1 to indicate either that the result is a result set or that there are no results. If the method getResultSet has already returned null, which means that the result is not a ResultSet object, then a return value of -1 has to mean that there are no more results. In other words, there are no results (or no more results) when th ((stmt.getResultSet() == null) && (stmt.getUpdateCount() == -1)) If one has called the method getResultSet and processed th etRes et to act esultSet turns null, as to call getUpdateCount to find out whether null n getMo esults retu alse, it means that the SQL statement returned an te count or that th no more results. So one n
Basic Java
147 .
getUpdateCount to find out which is the case. In this situation, there are no more sults when the following is true: ounts generated by a call to the method execute: stmt.getUpdateCount(); f (rowCount > 0) { // this is an update count " + count); lts(); s System.out.println(" No rows changed or statement was DDL command"); stmt.getMoreResults(); // use metadata to get info about result set columns ata in those rows through a set of get ethods that allow access to the various columns of the current row. The esultSet.next method is used to move to the next row of the ResultSet, making the come the current row. c re ((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1)) The code below demonstrates one way to be sure that one has accessed all the result sets and update c stmt.execute(queryStringWithUnknownResults); while (true) { int rowCount = i System.out.println("Rows changed = stmt.getMoreResu continue; } if (rowCount == 0) { // DDL command or 0 update continue; } // if we have gotten this far, we have either a result set // or no more results ResultSet rs = stmt.getResultSet; if (rs != null) { . . . while (rs.next()) { . . . // process results stmt.getMoreResults(); continue; } break; // there are no more results ResultSet A ResultSet contains all of the rows which satisfied the conditions in an SQL statement, and it provides access to the d mR next row be The general form of a result set is a table with column headings and the corresponding values returned by a query. For example, if your query is SELECT a, b, c FROM Table1, your result set will have the following form: a b ------ --------- ------- 12345 Cupertino CA 83472 Redmond WA 83492 Boston
MA Basic Java 148 . The following code fragment is an example of executing an SQL statement that will return a collection of rows, with column 1 as an int, column 2 as a String, and column 3 as an array of bytes: java.sql.Statement stmt = conn.createStatement(); ResultSet r = stmt.executeQuery("SELECT a, b, c FROM Table1"); while (r.next()) + s + " " + f); } the method next is called. Initially it is positioned efore the first row, so that the first call to next puts the cursor on the first row, tSet rows are retrieved in sequence from the top row ed. If a database allows positioned e cursor needs to be supplied as a nce. Either the column name or the column number can be used to designate the column from which to retrieve data. For example, if the second column of a ResultSet object rs is named "title" and stores values as strings, either of the following will retrieve the value stored in that column: String s = rs.getString("title"); String s = rs.getString(2); { // print the values for the current row. int i = r.getInt("a"); String s = r.getString("b"); float f = r.getFloat("c"); System.out.println("ROW = " + i + " " Rows and Cursors A ResultSet maintains a cursor which points to its current row of data. The cursor oves down one row each time mb making it the current row. Resul down as the cursor moves down one row with each successive call to next. A cursor remains valid until the ResultSet object or its parent Statement object is closed. In SQL, the cursor for a result table is nampdates or positioned deletes, the name of th u parameter to the update or delete command. This cursor name can be obtained by calling the method getCursorName. Note that not all DBMSs support positioned update and delete. The DatabaseMetaData.supportsPositionedDelete and supportsPositionedUpdate methods can be used to discover whether a particular connection supports these operations. When they are supported, the DBMS/driver must ensure that rows selected are properly locked so that positioned updates do not result in update anomalies or other concurrency problems. Columns The getXXX methods provide the means for retrieving column values from the current row. Within each row, column values may be retrieved in any order, but for maximum portability, one should retrieve values from left to right and read column values only o
Basic Java
149 .
Note that columns are numbered from left to right starting with column 1. Also, olumn names used as input to getXXX methods are case insensitive. e option of using the column name was prov h a ser who specifies column names in a query can use those same names as the arguments to getXXX methods. If, on the other hand, the l t column names (as in "select * from table1" or in ca s h e mn numbers should be used. In such situ o , r is no o ser to know for sure what the column names are. In some cases, it is possible for a SQL query to return a result set that has more than one column with the same name. If a column name is used as the parameter to a getXXX method, getXXX will return the value of the first matching column name. Thus, if there are multi0ple columns with the same name, one needs to use a column index to be sure that the correct column value is retrieved. It may also be slightly more efficient to use column numbers. Information about the columns in a ResultSet is available by calling the method ResultSet.getMetaData. The ResultSetMetaData object returned gives the number, types, and properties of its ResultSet object's columns. If the name of a column is known, but not its index, the method findColumn can be used to find the column number. Data Types and Conversions For the getXXX methods, the JDBC driver attempts to convert the underlying data to the specified Java type and then returns a suitable Java value. For example, if the getXXX method is getString, and the data type of the data in the underlying database AR, the JDBC dr r will convert VARCHAR to Java String. The return e a Java String object. The following table shows which JDBC types a getXXX method is allowed to retrieve and which JDBC types (generic SQL types) are recommended for it to retrieve. A small x indicates a legal getXXX method for a particular data type; a large X indicates the recommended getXXX method for a data type. For example, any getXXX method except getBytes or getBinaryStream can be used to retrieve the value of a LONGVARCHAR, but getAsciiStream or getUnicodeStream are recommended, depending on which data type is being returned. The method getObject will return any data type as a Java Object and is useful when the underlying data type is a database-specific abstract type or when a generic application needs to be able to accept any data type. Use of ResultSet.getXXX methods to retrieve common JDBC data types. An "x" indicates that the getXXX method may legally be used to retrieve the given JDBC type. An "X" indicates that the getXXX method is recommended for retrieving the given JDBC type. c Th ati ns sesethe ect staere em a ideent does d o at rived), u we column is d not specify y f sr te colu wa th u
ive
Basic Java
CI MA L NUME RI C BI T CHA R V A R C H A R L O N G V A R C H A R B I N A R Y V A R B I N A R Y LONGVARB I NAR Y DAT E TI ME TI MEST AMP getByte X x x x x x x x x x x x x getShort x X x x x x x x x x x x x getInt x x X x x x x x x x x x x getLong x x x X x x x x x x x x x getFloat x x x x X x x x x x x x x getDouble x x x x x X X x x x x x x getBigDecimal x x x x x x x X X x x x x getBoolean x x x x x x x x x X x x x getString x x x x x x x x x x X X x x x x x x x getBytes X X x getDate x x x X x getTime x x x X x getTimestamp x x x x X getAsciiStream x x X x x x getUnicodeStream x x X x x x getBinaryStream x x X GetObject x x x x x x x x x x x x x x x x x x x Using Streams for Very Large Row Values ResultSet makes it possible to retrieve arbitrarily large LONGVARBINARY or LONGVARCHAR data. The methods getBytes and getString return data as one large chunk (up to the limits imposed by the return value of Statement.getMaxFieldSize). However, it may be more convenient to retrieve very large data in smaller, fixed-size chunks. This is done by having the ResultSet class return java.io.Input streams from which data can be read in chunks. Note that these streams must be accessed immediately because they will be closed automatically on the next getXXX call on ResultSet. (This behavior is imposed by underlying implementation constraints on large blob access.) The JDBC API has three separate methods for getting streams, each with a different return value: getBinaryStream returns a stream which simply provides the raw bytes from the database without any conversion. getAsciiStream returns a stream which provides one-byte ASCII characters. Basic Java 151 . getUnicodeStream returns a stream which provides two-byte Unicode characters. Note that this differs from Java streams, which return untyped bytes and can (for example) be used for both ASCII and Unicode characters. The following code gives an example of using getAsciiStream: java.sql.Statement stmt = con.createStatement(); ResultSet r = stmt.executeQuery("SELECT x FROM Table2"); // Now retrieve the column 1 results in 4 K chunks: byte buff = new byte[4096]; while (r.next()) { Java.io.InputStream fin = r.getAsciiStream(1); for (;;) { int size = fin.read(buff); if (size == -1) { // at end of stream break; } // Send the newly-filled buffer to some ASCII output stream: output.write(buff, 0, size); } } NULL Result Values To determine if a given result value is JDBC NULL, one must first read the column and then use the ResultSet.wasNull method to discover if the read returned a JDBC NULL. When one has read a JDBC NULL using one of the ResultSet.getXXX methods, the method wasNull will return one of the following: A Java null value for those getXXX methods that return Java objects (methods such as getString, getBigDecimal, getBytes, getDate, getTime, getTimestamp, getAsciiStream, getUnicodeStream, getBinaryStream, getObject). A zero value for getByte, getShort, getInt, getLong, getFloat, and getDouble. A false value for getBoolean. Optional or Multiple Result Sets Normally SQL statements are executed using either executeQuery (which returns a single ResultSet) or executeUpdate (which can be used for any kind of database modification statement and which returns a count of the rows updated). However, under some circumstances an application may not know whether a given statement will return a result set until the statement has executed. In addition, some stored procedures may return several different result sets and/or update counts. To accommodate these situations, JDBC provides a mechanism so that an application can execute a statement and then process an arbitrary collection of result sets and update counts. This mechanism is based on first calling a fully general execute method, and then calling three other methods, getResultSet, getUpdateCount, and getMoreResults. These methods allow an application to explore the
statement results one at a time and to determine if a given result was a ResultSet or an update count. Basic Java 152 . You do not need to do anything to close a ResultSet; it is automatically closed by the Statement that generated it when that Statement is closed, is re-executed, or is used to retrieve the next result from a sequence of multiple results. PreparedStatement The PreparedStatement interface inherits from Statement and differs from it in two ways: 10. Instances of PreparedStatement contain an SQL statement that has already been compiled. This is what makes a statement "prepared." 11. The SQL statement contained in a PreparedStatement object may have one or more IN parameters. An IN parameter is a parameter whose value is not specified when the SQL statement is created. Instead the statement has a question mark ("?") as a placeholder for each IN parameter. A value for each question mark must be supplied by the appropriate setXXX method before the statement is executed. Because PreparedStatement objects are precompiled, their execution can be faster than that of Statement objects. Consequently, an SQL statement that is executed many times is often created as a PreparedStatement object to increase efficiency. Being a subclass of Statement, PreparedStatement inherits all the functionality of Statement. In addition, it adds a whole set of methods which are needed for setting the values to be sent to the database in place of the placeholders for IN parameters. Also, the three methods execute, executeQuery, and executeUpdate are modified so that they take no argument. The Statement forms of these methods (the forms that take an SQL statement parameter) should never be used with a PreparedStatement object. Creating PreparedStatement Objects The following code fragment, where con is a Connection object, creates a PreparedStatement object containing an SQL statement with two placeholders for IN parameters: PreparedStatement pstmt = con.prepareStatement( "UPDATE table4 SET m = ? WHERE x = ?"); The object pstmt now contains the statement "UPDATE table4 SET m = ? WHERE x = ?", which has already been sent to the DBMS and been prepared for execution. Passing IN Parameters Before a PreparedStatement object is executed, the value of each ? parameter must be set. This is done by calling a setXXX method, where XXX is the appropriate type for the parameter. For example, if the parameter has a Java type of long, the method to use is setLong. The first argument to the setXXX methods is the ordinal position of the parameter to be set, and the second argument is the value to which the parameter is to be set. For example, the following code sets the first parameter to 123456789 and the second parameter to 100000000: pstmt.setLong(1, 123456789); pstmt.setLong(2, 100000000); Once a parameter value has been set for a given statement, it can be used for multiple executions of that statement until it is cleared by a call to the method clearParameters. In the default mode for a connection (auto-commit enabled), each statement is commited or rolled back automatically when it is completed. Basic Java 153 . The same PreparedStatement object may be executed multiple times if the underlying database and driver will keep statements open after they have been committed. Unless this is the case, however, there is no point in trying to improve performance by using a PreparedStatement object in place of a Statement object. Using pstmt, the PreparedStatement object created above, the following code illustrates setting values for the two parameter placeholders and executing pstmt 10 times. As stated above, for this to work, the database must not close pstmt. In this example, the first parameter is set to "Hi" and remains constant. The second parameter is set to a different value each time around the for loop, starting with 0 and ending with 9. pstmt.setString(1, "Hi"); for (int i = 0; i < 10; i++) { pstmt.setInt(2, i); int rowCount =
pstmt.executeUpdate(); } Data Type Conformance on IN Parameters The XXX in a setXXX method is a Java type. It is implicitly a JDBC type (a generic SQL type) because the driver will map the Java type to its corresponding JDBC type and send that JDBC type to the database. For example, the following code fragment sets the second parameter of the PreparedStatement object pstmt to 44, with a Java type of short: pstmt.setShort(2, 44); The driver will send 44 to the database as a JDBC SMALLINT, which is the standard mapping from a Java short. It is the programmer's responsibility to make sure that the Java type of each IN parameter maps to a JDBC type that is compatible with the JDBC data type expected by the database. Consider the case where the database expects a JDBC SMALLINT. If the method setByte is used, the driver will send a JDBC TINYINT to the database. This will probably work because many databases convert from one related type to another, and generally a TINYINT can be used anywhere a SMALLINT is used. However, for an application to work with the most databases possible, it is best to use Java types that correspond to the exact JDBC types expected by the database. If the expected JDBC type is SMALLINT, using setShort instead of setByte will make an application more portable. Using setObject A programmer can explicitly convert an input parameter to a particular JDBC type by using the method setObject. This method can take a third argument, which specifies the target JDBC type. The driver will convert the Java Object to the specified JDBC type before sending it to the database. If no JDBC type is given, the driver will simply map the Java Object to its default JDBC type and then send it to the database. This is similar to what happens with the regular setXXX methods; in both cases, the driver maps the Java type of the value to the appropriate JDBC type before sending it to the database. The difference is that the setXXX methods use the standard mapping from Java types to JDBC types whereas the setObject method uses the mapping from Java Object types to JDBC types Basic Java 154 . The capability of the method setObject to accept any Java object allows an application to be generic and accept input for a parameter at run time. In this situation the type of the input is not known when the application is compiled. By using setObject, the application can accept any Java object type as input and convert it to the JDBC type expected by the database. Sending JDBC NULL as an IN parameter The setNull method allows a programmer to send a JDBC NULL value to the database as an IN parameter. Note, however, that one must still specify the JDBC type of the parameter. A JDBC NULL will also be sent to the database when a Java null value is passed to a setXXX method (if it takes Java objects as arguments). The method setObject, however, can take a null value only if the JDBC type is specified. Sending Very Large IN Parameters The methods setBytes and setString are capable of sending unlimited amounts of data. Sometimes, however, programmers prefer to pass in large blobs of data in smaller chunks. This can be accomplished by setting an IN parameter to a Java input stream. When the statement is executed, the JDBC driver will make repeated calls to this input stream, reading its contents and transmitting those contents as the actual parameter data. JDBC provides three methods for setting IN parameters to input streams: setBinaryStream for streams containing uninterpreted bytes, setAsciiStream for streams containing ASCII characters, and setUnicodeStream for streams containing Unicode characters. These methods take one more argument than the other setXXX methods because the total length of the stream must be specified. This is necessary because some databases need to know the total transfer size before any data is sent. The following code illustrates using a stream to send the contents of a file as an IN parameter: java.io.File file = new java.io.File("/tmp/data"); int fileLength =
file.length(); java.io.InputStream fin = new java.io.FileInputStream(file); java.sql.PreparedStatement pstmt = con.prepareStatement( "UPDATE Table5 SET stuff = ? WHERE index = 4"); pstmt.setBinaryStream (1, fin, fileLength); pstmt.executeUpdate(); When the statement executes, the input stream fin will get called repeatedly to deliver up its data. CallableStatement A CallableStatement object provides a way to call stored procedures in a standard way for all DBMSs. A stored procedure is stored in a database; the call to the stored procedure is what a CallableStatement object contains. This call is written in an escape syntax that may take one of two forms: one form with a result parameter, and the other without one. A result parameter, a kind of OUT parameter, is the return value for the stored procedure. Both forms may have a variable number of parameters used for input (IN parameters), output (OUT parameters), or both (INOUT parameters). A question mark serves as a placeholder for a parameter. Basic Java 155 . The syntax for invoking a stored procedure in JDBC is shown below. Note that the square brackets indicate that what is between them is optional; they are not themselves part of the syntax. {call procedure_name[(?, ?, ...)]} The syntax for a procedure that returns a result parameter is: {? = call procedure_name[(?, ?, ...)]} The syntax for a stored procedure with no parameters would look like this: {call procedure_name} Normally, anyone creating a CallableStatement object would already know that the DBMS being used supports stored procedures and what those procedures are. If one needed to check, however, various DatabaseMetaData methods will supply such information. For instance, the method supportsStoredProcedures will return true if the DBMS supports stored procedure calls, and the method getProcedures will return a description of the stored procedures available. CallableStatement inherits Statement methods, which deal with SQL statements in general, and it also inherits PreparedStatement methods, which deal with IN parameters. All of the methods defined in CallableStatement deal with OUT parameters or the output aspect of INOUT parameters: registering the JDBC types (generic SQL types) of the OUT parameters, retrieving values from them, or checking whether a returned value was JDBC NULL. Creating a CallableStatement Object CallableStatement objects are created with the Connection method prepareCall. The example below creates an instance of CallableStatement that contains a call to the stored procedure getTestData, which has two arguments and no result parameter: CallableStatement cstmt = con.prepareCall( "{call getTestData(?, ?)}"); Whether the ? placeholders are IN, OUT, or INOUT parameters depends on the stored procedure getTestData. IN and OUT Parameters Passing in any IN parameter values to a CallableStatement object is done using the setXXX methods inherited from PreparedStatement. The type of the value being passed in determines which setXXX method to use (setFloat to pass in a float value, and so on). If the stored procedure returns OUT parameters, the JDBC type of each OUT parameter must be registered before the CallableStatement object can be executed. (This is necessary because some DBMSs require the JDBC type.) Registering the JDBC type is done with the method registerOutParameter. Then after the statement has been executed, CallableStatement's getXXX methods retrieve the parameter value. The correct getXXX method to use is the Java type that corresponds to the JDBC type registered for that parameter. In other words, registerOutParameter uses a JDBC type (so that it matches the JDBC type that the database will return), and getXXX casts this to a Java type. To illustrate, the following code registers the OUT parameters, executes the stored procedure called by cstmt, and then retrieves the values returned in the OUT parameters. The method getByte retrieves a Java byte from the first OUT
parameter, Basic Java 156 . and getBigDecimal retrieves a BigDecimal object (with three digits after the decimal point) from the second OUT parameter: CallableStatement cstmt = con.prepareCall( "{call getTestData(?, ?)}"); cstmt.registerOutParameter(1, java.sql.Types.TINYINT); cstmt.registerOutParameter(2, java.sql.Types.DECIMAL, 3); cstmt.executeQuery(); byte x = cstmt.getByte(1); java.math.BigDecimal n = cstmt.getBigDecimal(2, 3); Unlike ResultSet, CallableStatement does not provide a special mechanism for retrieving large OUT values incrementally. INOUT Parameters A parameter that supplies input as well as accepts output (an INOUT parameter) requires a call to the appropriate setXXX method (inherited from PreparedStatement) in addition to a call to the method registerOutParameter. The setXXX method sets a parameter's value as an input parameter, and the method registerOutParameter registers its JDBC type as an output parameter. The setXXX method provides a Java value which the driver converts to a JDBC value before sending it to the database. The JDBC type of this IN value and the JDBC type supplied to the method registerOutParameter should be the same. Then to retrieve the output value, a corresponding getXXX method is used. For example, a parameter whose Java type is byte should use the method setByte to assign the input value, should supply a TINYINT as the JDBC type to registerOutParameter, and should use getByte to retrieve the output value. The following example assumes that there is a stored procedure reviseTotal whose only parameter is an INOUT parameter. The method setByte sets the parameter to 25, which the driver will send to the database as a JDBC TINYINT. Next registerOutParameter registers the parameter as a JDBC TINYINT. After the stored procedure is executed, a new JDBC TINYINT value is returned, and the method getByte will retrieve this new value as a Java byte. CallableStatement cstmt = con.prepareCall( "{call reviseTotal(?)}"); cstmt.setByte(1, 25); cstmt.registerOutParameter(1, java.sql.Types.TINYINT); cstmt.executeUpdate(); byte x = cstmt.getByte(1); Retrieve OUT Parameters after Results Because of limitations imposed by some DBMSs, it is recommended that for maximum portability, all of the results generated by the execution of a CallableStatement object should be retrieved before OUT parameters are retrieved using CallableStatement.getXXX methods. If a CallableStatement object returns multiple ResultSet objects (using a call to the method execute), all of the results should be retrieved before OUT parameters are retrieved. In this case, to be sure that all results have been accessed, the Statement methods getResultSet, getUpdateCount, and getMoreResults need to be called until there are no more results. Basic Java 157 . After this is done, values from OUT parameters can be retrieved using the CallableStatement.getXXX methods. Retrieving NULL Values as OUT Parameters The value returned to an OUT parameter may be JDBC NULL. When this happens, the JDBC NULL value will be converted so that the value returned by a getXXX method will be null, 0, or false, depending on the getXXX method type. As with ResultSet objects, the only way to know if a value of 0 or false was originally JDBC NULL is to test it with the method wasNull, which returns true if the last value read by a getXXX method was JDBC NULL and false otherwise. Mapping SQL and Java Types Since SQL data types and Java data types are not identical, there needs to be some mechanism for reading and writing data between an application using Java types and a database using SQL types. To accomplish this, JDBC provides sets of getXXX and setXXX methods, the method registerOutParameter, and the class Types. This section brings together information about data types affecting various classes and interfaces and puts all the tables showing the mappings between SQL types and Java types in
one place for easy reference. Mapping SQL Data Types into Java Unfortunately there are significant variations between the SQL types supported by different database products. Even when different databases support SQL types with the same semantics, they may give those types different names. For example, most of the major databases support an SQL data type for large binary values, but Oracle calls this type LONG RAW, Sybase calls it IMAGE, Informix calls it BYTE, and DB2 calls it LONG VARCHAR FOR BIT DATA. Fortunately, JDBC programmers will normally not need to concern themselves with the actual SQL type names used by a target database. Most of the time JDBC programmers will be programming against existing database tables, and they need not concern themselves with the exact SQL type names that were used to create these tables. JDBC defines a set of generic SQL type identifiers in the class java.sql.Types. These types have been designed to represent the most commonly used SQL types. In programming with the JDBC API, programmers will normally be able to use these JDBC types to reference generic SQL types, without having to be concerned about the exact SQL type name used by the target database. These JDBC types are fully described in the next section. The one major place where programmers may need to use SQL type names is in the SQL CREATE TABLE statement when they are creating a new database table. In this case programmers must take care to use SQL type names that are supported by their target database. We recommend that you consult your database documentation if you need exact definitions of the behavior of the various SQL types on a particular database. Basic Java 158 . If you want to be able to write portable JDBC programs that can create tables on a variety of different databases, you have two main choices. First, you can restrict yourself to using only very widely accepted SQL type names such as INTEGER, NUMERIC, or VARCHAR, which are likely to work for all databases. Or second, you can use the java.sql.DatabaseMetaData.getTypeInfo method to discover which SQL types are actually supported by a given database and select a database-specific SQL type name that matches a given JDBC type. JDBC defines a standard mapping from the JDBC database types to Java types. For example, a JDBC INTEGER is normally mapped to a Java int. This supports a simple interface for reading and writing JDBC values as simple Java types. The Java types do not need to be exactly isomorphic to the JDBC types; they just need to be able to represent them with enough type information to correctly store and retrieve parameters and recover results from SQL statements. For example, a Java String object does not precisely match any of the JDBC CHAR types, but it gives enough type information to represent CHAR, VARCHAR, or LONGVARCHAR successfully. Examples of Mapping In any situation where a Java program retrieves data from a database, there has to be some form of mapping and data conversion. In most cases, JDBC programmers will be programming with knowledge of their target database's schema. They would know, for example, what tables the database contains and the data type for each column in those tables. They can therefore use the strongly-typed access methods in the interfaces ResultSet, PreparedStatement, and CallableStatement. This section presents three different scenarios, describing the data mapping and conversion required in each. Simple SQL Statement In the most common case, a user executes a simple SQL statement and gets back a ResultSet object with the results. The value returned by the database and stored in a ResultSet column will have a JDBC data type. A call to a ResultSet.getXXX method will retrieve that value as a Java data type. For example, if a ResultSet column contains a JDBC FLOAT value, the method getDouble will retrieve that value as a Java double. The getXXX methods
may be used to retrieve which JDBC types. (A user who does not know the type of a ResultSet column can get that information by calling the method ResultSet.getMetaData and then invoking the ResultSetMetaData methods getColumnType or getColumnTypeName.) The following code fragment demonstrates getting the column type names for the columns in a result set: String query = "select * from Table1"; ResultSet rs = stmt.executeQuery(query); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); for (int i = 1; i <= columnCount; i++) { String s = rsmd.getColumnTypeName(i); System.out.println ("Column " + i + " is type " + s); } Basic Java 159 . SQL Statement with IN Parameters In another possible scenario, the user sends an SQL statement which takes input parameters. In this case, the user calls the PreparedStatement.setXXX methods to assign a value to each input parameter. For example, PreparedStatement.setLong(1, 2345678) will assign the value 2345678 to the first parameter as a Java long. The driver will convert 2345678 to a JDBC BIGINT in order to send it to the database. Which JDBC type the driver sends to the database is determined by the standard mapping from Java types to JDBC types. SQL Statement with INOUT Parameters In yet another scenario, a user wants to call a stored procedure, assign values to its INOUT parameters, retrieve values from the results, and retrieve values from the parameters. This case is rather uncommon and more complicated than most, but it gives a good illustration of mapping and data conversion. In this scenario, the first thing to do is to assign values to the INOUT parameters using PreparedStatement.setXXX methods. In addition, since the parameters will also be used for output, the programmer must register each parameter with the JDBC type of the value that the database will return to it. This is done with the method CallableStatement.registerOutParameter, which takes one of the JDBC types defined in the class Types. A programmer retrieves the results returned to a ResultSet object with ResultSet.getXXX methods and retrieves the values stored in the output parameters with CallableStatement.getXXX methods. The XXX type used for ResultSet.getXXX methods is fairly flexible in some cases. The XXX type used for CallableStatement.getXXX must map to the JDBC type registered for that parameter. For example, if the database is expected to return an output value whose type is JDBC REAL, the parameter should have been registered as java.sql.Types.REAL. Then to retrieve the JDBC REAL value, the method CallableStatement.getFloat should be called. The method getFloat will return the value stored in the output parameter after converting it from a JDBC REAL to a Java float. To accommodate various databases and make an application more portable, it is recommended that values be retrieved from ResultSet objects before values are retrieved from output parameters. The following code demonstrates calling a stored procedure named getTestData, which has two parameters that are both INOUT parameters. First the Connection object con creates the CallableStatement object cstmt. Then the method setByte sets the first parameter to 25 as a Java byte. The driver will convert 25 to a JDBC TINYINT and send it to the database. The method setBigDecimal sets the second parameter with an input value of 83.75. The driver will convert this java.math.BigDecimal object to a JDBC NUMERIC value. Next the two parameters are registered as OUT parameters, the first parameter as a JDBC TINYINT and the second parameter as a JDBC DECIMAL with two digits after the decimal point. After cstmt is executed, the values are retrieved from the ResultSet object using ResultSet.getXXX methods. The method getString gets the value in the first column as a Java String object, getInt gets the value in the second column as a Java int, and getInt gets the value in the third column as a Java int.
Then CallableStatement.getXXX methods retrieve the values stored in the output parameters. The method getByte retrieves the JDBC TINYINT as a Java byte, and getBigDecimal retrieves the JDBC DECIMAL as a java.math.BigDecimal object with Basic Java 160 . two digits after the decimal point. Note that when a parameter is both an input and an output parameter, the setXXX method uses the same Java type as the getXXX method (as in setByte and getByte). The registerOutParameter method registers it to the JDBC type that is mapped from the Java type CallableStatement cstmt = con.prepareCall( "{call getTestData(?, ?)}"); cstmt.setByte(1, 25); cstmt.setBigDecimal(2, 83.75); // register the first parameter as a JDBC TINYINT and the second //parameter as a JDBC DECIMAL with two digits after the decimal point cstmt.registerOutParameter(1, java.sql.Types.TINYINT); cstmt.registerOutParameter(2, java.sql.Types.DECIMAL, 2); ResultSet rs = cstmt.executeUpdate(); // retrieve and print values in result set while(rs.next()) { String name = rs.getString(1); int score = rs.getInt(2); int percentile = rs.getInt(3); System.out.print("name = " + name + ", score = " + score + ", " System.out.println("percentile = " + percentile); // retrieve values in output parameters byte x = cstmt.getByte(1); java.math.BigDecimal n = cstmt.getBigDecimal(2, 2); To generalize, the XXX in CallableStatement.getXXX and PreparedStatement.setXXX methods is a Java type. For setXXX methods, the driver converts the Java type to a JDBC type before sending it to the database. For getXXX methods, the driver converts the JDBC type returned by the database to a Java type before returning it to the getXXX method. The method registerOutParameter always takes a JDBC type as an argument, and the method setObject may take a JDBC type as an argument. Note that if a JDBC type is supplied in its optional third argument, the method setObject will cause an explicit conversion of the parameter value from a Java type to the JDBC type specified. If no target JDBC type is supplied to setObject, the parameter value will be converted to the JDBC type that is the standard mapping from the Java. The driver will perform the explicit or implicit conversion before sending the parameter to the database. Dynamic Data Access In most cases, the user wants to access results or parameters whose data types are known at compile time. However, some applications, such as generic browsers or query tools, are compiled with no knowledge of the database schema they will access. For this reason, JDBC provides support for fully dynamically-typed data access in addition to static data type access. Three methods and one constant facilitate accessing values whose data types are not known at compile time: ResultSet.getObject PreparedStatement.setObject CallableStatement.getObject Basic Java 161 . java.sql.Types.OTHER (used as an argument to CallableStatement.registerOutParameter) If, for example, an application wants to be able to accept a variety of types as results in a ResultSet object, it can use the method ResultSet.getObject. The methods ResultSet.getObject and CallableStatement.getObject retrieve a value as a Java Object. Since Object is the base class for all Java objects, an instance of any Java class can be retrieved as an instance of Object. However, the following Java types are built-in "primitive" types and are therefore not instances of the class Object: boolean, char, byte, short, int, long, float, and double. As a result, these types cannot be retrieved by getObject methods. However, each of these primitive types has a corresponding class that serves as a wrapper. Instances of these classes are objects, which means that they can be retrieved with the methods ResultSet.getObject and CallableStatement.getObject The method getObject can also be used to retrieve user-defined Java types. With the advent of abstract data types (ADTs) or other user-defined types in some database systems, some
vendors may find it convenient to use getObject for retrieving these types. Tables for Data Type Mapping JDBC type Java type CHAR String VARCHAR String LONGVARCHAR String NUMERIC java.math.BigDecimal DECIMAL java.math.BigDecimal BIT boolean TINYINT byte SMALLINT short INTEGER int BIGINT long REAL float FLOAT double DOUBLE double BINARY byte[] VARBINARY byte[] LONGVARBINARY byte[] DATE java.sql.Date TIME java.sql.Time TIMESTAMP java.sql.Timestamp Basic Java 162 . Java Types Mapped to JDBC Types Java Type JDBC type String VARCHAR or LONGVARCHAR java.math.BigDecimal NUMERIC boolean BIT byte TINYINT short SMALLINT int INTEGER long BIGINT float REAL double DOUBLE byte[] VARBINARY or LONGVARBINARY java.sql.Date DATE java.sql.Time TIME java.sql.Timestamp TIMESTAMP The mapping for String will normally be VARCHAR but will turn into LONGVARCHAR if the given value exceeds the driver's limit on VARCHAR values. The same is true for byte[] and VARBINARY and LONGVARBINARY values. JDBC Types Mapped to Java Object Types Since the Java built-in types such as boolean and int are not subtypes of Object, there is a slightly different mapping from JDBC types to Java object types for the getObject/setObject methods. This mapping is shown in the following table: JDBC Type Java Object Type CHAR String VARCHAR String LONGVARCHAR String NUMERIC java.math.BigDecimal DECIMAL java.math.BigDecimal BIT Boolean TINYINT Integer SMALLINT Integer INTEGER Integer BIGINT Long REAL Float FLOAT Double DOUBLE Double BINARY byte[] VARBINARY byte[] LONGVARBINARY byte[] DATE java.sql.Date TIME java.sql.Time Basic Java 163 . TIMESTAMP java.sql.Timestamp Java Object Types Mapped to JDBC Types Java Object Type JDBC Type String VARCHAR or LONGVARCHAR java.math.BigDecimal NUMERIC Boolean BIT Integer INTEGER Long BIGINT Float REAL Double DOUBLE byte[] VARBINARY or LONGVARBINARY java.sql.Date DATE java.sql.Time TIME java.sql.Timestamp TIMESTAMP Note that the mapping for String will normaly be VARCHAR but will turn into LONGVARCHAR if the given value exceeds the driver's limit on VARCHAR values. The case is similar for byte[] and VARBINARY and LONGVARBINARY values. Conversions by setObject The method setObject converts Java object types to JDBC types. TI NY I NT SMALL I NT I NT EGE R BI GI NT RE AL FLOA T DOUBL E DE CI MA L NUME RI C BI T CHA R V A R C H A R L O N G V A R C H A R B I N A R Y V A R B I N A R Y LONGVARB I NAR Y DAT E TI ME TI MEST AMP String x x x x x x x x x x x x x x x x x x x java.math.BigDecimal x x x x x x x x x x x x x Boolean x x x x x x x x x x x x x Integer x x x x x x x x x x x x x Long x x x x x x x x x x x x x Float x x x x x x x x x x x x x Double x x x x x x x x x x x x x byte[] x x x java.sql.Date x x x x x java.sql.Time x x x x java.sql.Time- stamp x x x x x x Basic Java 164 . JDBC Types Retrieved by ResultSet.getXXX Methods An "x" means that the method can retrieve the JDBC type. An "X" means that the method is recommended for the JDBC type. T I N Y I N T SMALL I NT I NT EGE R BI GI NT RE AL FLOA T DOUBL E DE CI MA L NUME RI C BI T CHA R V A R C H A R L O N G V A R C H A R B I N A R Y V A R B I N A R Y LONGVARB I NAR Y DAT E TI ME TI MEST AMP getByte X x x x x x x x x x x x x getShort x X x x x x x x x x x x x getInt x x X x x x x x x x x x x getLong x x x X x x x x x x x x x getFloat x x x x X x x x x x x x x getDouble x x x x x X X x x x x x x getBigDecimal x x x x x x x X X x x x x getBoolean x x x x x x x x x X x x x getString x x x x x x x x x x X X x x x x x x x getBytes X X x getDate x x x X x getTime x x x X x getTimestamp x x x x X getAsciiStream x x X x x x getUnicodeStream x x X x x x getBinaryStream x x X getObject x x x x x x x x x x x x x x x
x x x x Basic Java 165 . Sample Code // The following code can be used as a template. Simply // substitute the appropriate url, login, and password, and then substitute //the // SQL statement you want to send to the database. //--------------------------------------------------------- ------------------ // // Module: SimpleSelect.java // // Description: //Test program for ODBC API interface. //This java application will connect to //a JDBC driver, //issue a select statement // and display all result columns and rows //--------------------------------------------------------- ------------------ import java.net.URL; import java.sql.*; class SimpleSelect { public static void main (String args[]) { String url = "jdbc:odbc:my-dsn"; String query = "SELECT * FROM emp"; try { // Load the jdbc-odbc bridge driver Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver"); DriverManager.setLogStream(System.out); // Attempt to connect to a driver. Each one // of the registered drivers will be loaded until // one is found that can process this URL Connection con = DriverManager.getConnection ( url, "my-user", "my-passwd"); // If we were unable to connect, an exception // would have been thrown. So, if we get here, // we are successfully connected to the URL // Check for, and display and warnings generated // by the connect. checkForWarning (con.getWarnings ()); // Get the DatabaseMetaData object and display // some information about the connection DatabaseMetaData dma = con.getMetaData (); System.out.println("\nConnected to " + dma.getURL()); System.out.println("Driver " + dma.getDrive System.out.println("Version " +dma.getDriverVersion()); System.out.println(""); Basic Java 166 . // Create a Statement object so we can submit // SQL statements to the driver Statement stmt = con.createStatement (); // Submit a query, creating a ResultSet object ResultSet rs = stmt.executeQuery (query); // Display all columns and rows from the result set dispResultSet (rs); // Close the result set rs.close(); // Close the statement stmt.close(); // Close the connection con.close(); } catch (SQLException ex) { // A SQLException was generated. Catch it and // display the error information. Note that there // could be multiple error objects chained // together System.out.println ("\n*** SQLException caught ***\n"); while (ex != null) { System.out.println ("SQLState: " +ex.getSQLState ()); System.out.println ("Message: " + ex.getMessage ()); System.out.println ("Vendor: " +ex.getErrorCode ()); ex = ex.getNextException (); System.out.println (""); } } catch (java.lang.Exception ex) { // Got some other type of exception. Dump it. ex.printStackTrace (); } } //--------------------------------------------------------- --------- // checkForWarning // Checks for and displays warnings. Returns true if a warning // existed Basic Java 167 . //---------------------------------------------------------- ---------
private static boolean checkForWarning (SQLWarning warn) throws SQLException { boolean rc = false; // If a SQLWarning object was given, display the // warning messages. Note that there could be // multiple warnings chained together if (warn != null) { System.out.println ("\n *** Warning ***\n"); rc = true; while (warn != null) { System.out.println ("SQLState: " +warn.getSQLState ()); System.out.println ("Message: " +warn.getMessage ()); System.out.println ("Vendor: " +warn.getErrorCode ()); System.out.println (""); warn = warn.getNextWarning (); } } return rc; } //---------------------------------------------------------- -------- // dispResultSet // Displays all columns and rows in the given result set //--------------------------------------------------------- --------- private static void dispResultSet (ResultSet rs) throws SQLException { int i; // Get the ResultSetMetaData. This will be used for // the column headings ResultSetMetaData rsmd = rs.getMetaData (); // Get the number of columns in the result set int numCols = rsmd.getColumnCount (); // Display column headings for (i=1; i<=numCols; i++) { Basic Java 168 . if (i > 1) System.out.print(","); System.out.print(rsmd.getColumnLabel(i)); } System.out.println(""); // Display data, fetching until end of the result set boolean more = rs.next (); while (more) { // Loop through each column, getting the // column data and displaying for (i=1; i<=numCols; i++) { if (i > 1) System.out.print(","); System.out.print(rs.getString(i)); } System.out.println(""); // Fetch the next result set row more = rs.next (); } } } JDBC-ODBC Bridge Driver If possible, use a Pure Java JDBC driver instead of the Bridge and an ODBC driver. This completely eliminates the client configuration required by ODBC. It also eliminates the potential that the Java VM could be corrupted by an error in the native code brought in by the Bridge (that is, the Bridge native library, the ODBC driver manager library, the ODBC driver library, and the database client library). What Is the JDBC-ODBC Bridge? The JDBC-ODBC Bridge is a JDBC driver which implements JDBC operations by translating them into ODBC operations. To ODBC it appears as a normal application program. The Bridge implements JDBC for any database for which an ODBC driver is available. The Bridge is implemented as the sun.jdbc.odbc Java package and contains a native library used to access ODBC. The Bridge is a joint development of Intersolv and JavaSoft. What Version of ODBC Is Supported? The bridge supports ODBC 2.x. This is the version that most ODBC drivers currently support. It will also likely work with most forthcoming ODBC 3.x drivers; however, this has not been tested. Basic Java 169 . The Bridge Implementation The Bridge is implemented in Java and uses Java native methods to call ODBC. Installation The Bridge is installed automatically with the JDK as package sun.jdbc.odbc. See your ODBC driver vendor for information on installing and configuring ODBC. No special configuration is required for the Bridge. See your database vendor for client installation and configuration information. On Solaris, some ODBC driver managers name their libs libodbcinst.so and libodbc.so. The Bridge expects these libraries to be named libodbcinst.so.1 and libodbc.so.1, so symbolic links for these names must be created. Using the
Bridge The Bridge is used by opening a JDBC connection using a URL with the odbc subprotocol. See below for URL examples. Before a connection can be established, the bridge driver class, sun.jdbc.odbc.JdbcOdbcDriver, must either be added to the java.lang.System property named jdbc.drivers, or it must be explicitly loaded using the Java class loader. Explicit loading is done with the following line of code: Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); When loaded, the ODBC driver (like all good JDBC drivers) creates an instance of itself and registers this with the JDBC driver manager. Using the Bridge from an Applet JDBC used with a Pure Java JDBC driver works well with applets. The Bridge driver does not work well with applets. Most Browsers Do Not Support the Bridge Since the Bridge is an optional component of the JDK, it may not be provided by a browser. Even if it is provided, only trusted applets (those allowed to write to files) will be able to use the Bridge. This is required in order to preserve the security of the applet sandbox. Finally, even if the applet is trusted, ODBC and the DBMS client library must be configured on each client. Tested Configurations From Solaris, we have used the Bridge to access Oracle 7.1.6 and Sybase Version 10 running on Solaris. From NT, we have used the Bridge to access SQL Server 6.x. ODBC Drivers Known to Work with the Bridge Visigenic provides ODBC drivers which have been tested with the the Bridge. Drivers are available for Oracle, Sybase, Informix, Microsoft SQL Server, and Ingres. To purchase the ODBC DriverSet 2.0, please contact Visigenic sales at 415-312-7197, or visit the web site www.visigenic.com. The INTERSOLV ODBC driver suite should be completely compatible with the JDBC-ODBC Bridge. The following drivers have successfully passed a minimal test suite: Oracle, xBASE, Sybase (Windows NT/95 Basic Java 170 . Basic Java 171 only), Microsoft SQL-Server, and Informix. To evaluate or purchase INTERSOLV ODBC drivers, please contact INTERSOLV DataDirect Sales at 1- 800-547-4000 Option 2 or via the World Wide Web at http:\\www.intersolv.com. The MS SQL Server driver has also been used successfully on NT. Many other ODBC drivers will likely work. ODBC Driver Incompatibilities On Solaris, we have found that the Sybase ctlib-based drivers don't work because ctlib has a signal-handling conflict with the Java VM. This is likely not a problem on NT due to differences in the NT Java VM; however, this has not been verified. Some ODBC drivers only allow a single result set to be active per connection. What Is the JDBC URL Supported by the Bridge? The Bridge driver uses the odbc subprotocol. URLs for this subprotocol are of the form: jdbc:odbc:<data-source-name>[<attribute-name>=<attribute-value>]* For example: jdbc:odbc:sybase jdbc:odbc:mydb;UID=me;PWD=secret jdbc:odbc:ora123;Cachesize=300 Debugging The Bridge provides extensive tracing when DriverManager tracing is enabled. The following line of code enables tracing and sends it to standard out: java.sql.DriverManager.setLogStream(java.lang.System.out); General Notes The Bridge assumes that ODBC drivers are not reentrant. This means the Bridge must synchronize access to these drivers. The result is that the Bridge provides limited concurrency. This is a limitation of the Bridge. Most Pure Java JDBC drivers provide the expected level of concurrent access.