By Ian F. Darwin
Book Price: $49.95 USD
£31.95 GBP
PDF Price: $39.99
Cover | Table of Contents | Colophon
C:\javasrc>javac HelloWorld.java C:\javasrc>java HelloWorld Hello, World C:\javasrc>
C:\javasrc>javac HelloWorld.java C:\javasrc>java HelloWorld Hello, World C:\javasrc>
javac and java. In older
versions of Java you had to set your CLASSPATH to include
".", even to run a simple program
from the current directory; this is no longer true on
Sun's current Java implementations. It may be true
on some of the clones.http://www.textpad.com), Visual Slick Edit,
and others are low-cost windowed editors (primarily for Windows) that
have some amount of Java recognition built-in and the ability to
compile from within the editor. TextPad recognizes quite a number of
file types, including batch files and shell scripts, C, C++, Java,
JSP, JavaScript, and many others. For each of these, it uses color
highlighting to show which part of the file being edited comprises
keywords, comments, quoted strings, and so on. This is very useful in
spotting when part of your code has been swallowed up by an
unterminated /* comment or a missing quote. While
this isn't the same as the deep understanding of
Java that a full IDE might possess, experience has shown that it
definitely aids programmer productivity. TextPad also has a
"compile Java" command and a
"run external program" command.
Both of these have the advantage of capturing the entire command
output into a window, which may be easier to scroll than a
command-line window on some platforms. On the other hand, you
don't see the command results until the program
terminates, which can be most uncomfortable if your GUI application
throws an exception before it puts up its main window. Despite this
minor drawback, TextPad is a very useful tool. Other editors that
include color highlighting include
vim
(an enhanced version of the Unix tool
vi, available for Windows and Unix platforms
from http://www.vim.org), the
ever-popular Emacs editor, and many others.The JDK software comes with a minimal set of tools. Serious developers are advised to use a professional Integrated Development Environment with JDK 1.2 software. Click on one of the images below to visit external sites and learn more.
java -classpath \c:\ian\classes MyProg
trace,
strace, truss,
ktrace), you would probably see the
Java program open (or
stat, or access) the following
files:sun.boot.class.path = C:\JDK1.4\JRE\lib\rt.jar;C:\JDK1.4\JRE\lib\i18n.jar;C:\JDK1.4\ JRE\classes
com.darwinsys.util
package from the first edition of this
book into about a dozen com.darwinsys packages,
listed in Table 1-1. I have also added many new
classes; these packages now include approximately 50 classes and
interfaces. You can peruse the documentation online at http://javacook.darwinsys.com/docs/api.|
Package name
|
Package description
|
|---|---|
com.darwinsys.database
|
Classes for dealing with databases in a general way
|
com.darwinsys.html
|
Classes (only one so far) for dealing with HTML
|
com.darwinsys.io
|
Classes for input and output operations, using
Java's underlying I/O classes
|
com.darwinsys.lang
|
http://javacook.darwinsys.com/. You can get
it all as one large file containing all the source code, in a file
called javacooksrc.jar, which you should unzip
into an empty directory someplace convenient, wherever
you like to keep source
code. You should then edit the file
build.properties, specifying the locations of
some jar files. Editing build.properties and
then running ant in this directory first creates a
file called darwinsys.jar
containing the
com.darwinsys API described in Recipe 1.5 (you will probably want to add this file to
your CLASSPATH—see Recipe 1.4—or
to your JDKHOME/jre/lib/ext directory). Ant goes
on to build as many of the other examples as it can given the
settings in build.properties, your Java runtime,
and your operating system. The files are roughly organized in
per-chapter directories, but there is a lot of overlap and
cross-referencing. Because of this, I have prepared a cross-reference
file named index-bychapter.html. A mechanically
generated file called index-byname.html can be
used if you know the name of the file you want (and remember that
Java source files almost always have the same name as the public
class they contain).
The canonical index file,
index.html, links to both these files.http://jakarta.apache.org/ant/.
Like make, Ant uses a file or
files—written in
XML—listing what to do and, if
necessary, how to do it. These rules are intended to be
platform-independent, though you can of course write
platform-specific recipes if necessary.<!-
- tag begins an XML
comment, which extends to the -
-> tag.<project name="Java Cookbook Examples" default="compile" basedir=".">
<!-- Set global properties for this build -->
<property name="src" value="."/>
<property name="build" value="build"/>
<!-- Specify the compiler to use.
Using jikes is supported but requires rt.jar in classpath. -->
<property name="build.compiler" value="modern"/>
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>
<!-- Specify what to compile. This builds everything -->
<target name="compile" depends="init">
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"
classpath="../darwinsys.jar"/>
</target>
</project>$ ant compile
Buildfile: build.xml
Project base dir set to: /home/ian/javasrc/starting
Executing Target: init
Executing Target: compile
Compiling 19 source files to /home/ian/javasrc/starting/build
Performing a Modern Compile
Copying 22 support files to /home/ian/javasrc/starting/build
Completed in 8 seconds
$java.applet.Applet;
write some HTML and point a browser at it.java.applet.Applet, and in doing so inherits the
functionality it needs to be viewable inside a web page in a
Java-enabled web
browser.
All that's necessary is an HTML page referring to
the applet. This
HTML page requires an
applet tag with a minimum of three
attributes
, or modifiers: the name of the applet
itself and its onscreen width and height in screen dots or pixels.
This is not the place for me to teach you HTML syntax—there is
some of that in Recipe 18.1—but
I'll show my HTML applet template file. Many of the
IDEs write a page like this if you use
their "build new applet" wizards:<html> <head><title>A Demonstration</title></head> <body> <h1>My TEMPLATE Applet</h1> <applet code="CCC" width="200" height="200"> </applet> </body> </html>
code="com.foo.MyApplet") and placed it in the same
directory as the class file, you need only tell a Java-enabled web
browser to view the HTML page, and the applet should be included in
it.AppletViewer
, a kind of mini-browser included in the
JDK. You need to give it the HTML file, just like a regular browser.
Sun's AppletViewer (shown in Figure 1-9 under Windows) has an explicit Reload button
that actually reloads the applet. And it has other features, such as
debugging hooks, and other information displays. It also has a View java.util.Date
class
had some serious limitations with regard to internationalization.
Accordingly, many of the Date class methods and
constructors are marked
"deprecated." To
deprecate something means, according to the
American Heritage Dictionary, to
"express disapproval of; deplore."
Java's developers are therefore disapproving of the
old way of doing things. Try compiling this code:import java.util.Date;
/** Demonstrate deprecation warning */
public class Deprec {
public static void main(String[] av) {
// Create a Date object for May 5, 1986
// EXPECT DEPRECATION WARNING
Date d = new Date(86, 04, 05); // May 5, 1986
System.out.println("Date is " + d);
}
}C:\javasrc>javac Deprec.java
Note: Deprec.java uses or overrides a deprecated API. Recompile with
"-deprecation" for details.
1 warning
C:\javasrc>-deprecation
(if using Ant, use <javac
deprecation= 'true '...>)
for details:C:\javasrc>javac -deprecation Deprec.java
Deprec.java:10: warning: constructor Date(int,int,int) in class java.util.Date has
been deprecated
Date d = new Date(86, 04, 05); // May 5, 1986
^
1 warning
C:\javasrc>Date constructor that
takes three integer arguments has been deprecated. How do you fix it?
The answer is, as in most questions of usage, to refer to the
Javadoc documentation for the class. In Java
2, the introduction to the if statement
whose value is known to be false at compile
time. Why should it even generate code for the
condition? True, you say, but how can the results of an
if statement be known at compile time? Simple:
through final
boolean variables.
Further, if the value of the if condition is known
to be false, then the body of the if statement
should not be emitted by the compiler either. Presto—instant
conditional compilation!// IfDef.java
final boolean DEBUG = false;
System.out.println("Hello, World ");
if (DEBUG) {
System.out.println("Life is a voyage, not a destination");
}Debug class.if statement is not all that great.
Let's combine the flexibility of runtime checking
with the simple if statement to debug a
hypothetical
fetch( ) method
(part of Fetch.java):String name = "poem";
if (System.getProperty("debug.fetch") != null) {
System.err.println("Fetching " + name);
}
value = fetch(name);-D
argument to enable debug.fetch, the printout
occurs:> java Fetch # See? No output > java -Ddebug.fetch Fetch Fetching poem >
if statement is tedious to
write in large quantities, so I have encapsulated it into a
Debug
class, which is part of my
com.darwinsys.util package.
Debug.java appears in full in Recipe 1.17 at the end of this chapter. My
Debug class also provides the string
"debug." as part of the argument to
System.getProperty(
)
, so we can simplify the previous
Fetch example as follows (code in
FetchDebug.java):String name = "poem", value;
Fetch f = new Fetch( );
Debug.println("fetch", "Fetching " + name);
value = f.fetch(name);Fetch:> java FetchDebug # again, no output > java -Ddebug.fetch FetchDebug Fetching poem >
assert. The
assert keyword takes two arguments separated by a
colon (by analogy with the conditional operator): an expression that
is asserted by the developer to be true, and a message to be included
in the exception that is thrown if the expression is false. To
provide for backward compatibility with programs that might have used
"assert" as an identifier name on
prior JDK versions,
JDK 1.4 requires a
command-line switch (-source
1.4) that must be provided for
assert to be recognized as a keyword. Normally,
assertions are meant to be left in place (unlike quick and dirty
print statements, which are often put in during one test and then
removed). To reduce runtime overhead, assertion checking is not
enabled by default; it must be enabled explicitly with the
-enableassertions
(or -ea)
command-line flag. Here is a simple demo program that shows the use
of the assertion mechanism:ian:147$ cd testing; ian:148$ cat AssertDemo.java public class AssertDemo { public static void main(String[] args) { int i = 4; if (args.length == 1) { i = Integer.parseInt(args[0]); } assert i > 0 : "i is non-positive"; System.out.println("Hello after an assertion"); } } ian:149$ javac -source 1.4 AssertDemo.java # will not compile without 1.4 flag ian:150$ java AssertDemo -1 Hello after an assertion ian:151$ java -ea AssertDemo -1 Exception in thread "main" java.lang.AssertionError: i is non-positive at AssertDemo.main(AssertDemo.java:15) ian:152$
/** This program exhibits some bugs, so we can use a debugger */
public class Buggy {
static String name;
public static void main(String[] args) {
int n = name.length( ); // bug # 1
System.out.println(n);
name += "; The end."; // bug #2
System.out.println(name); // #3
}
}ian> java Buggy Exception in thread "main" java.lang.NullPointerException at Buggy.main(Compiled Code) ian> jdb Buggy Initializing jdb... 0xb2:class(Buggy) > run run Buggy running ... main[1] Uncaught exception: java.lang.NullPointerException at Buggy.main(Buggy.java:6) at sun.tools.agent.MainThread.runMain(Native Method) at sun.tools.agent.MainThread.run(MainThread.java:49) main[1] list 2 public class Buggy { 3 static String name; 4 5 public static void main(String[] args) { 6 => int n = name.length( ); // bug # 1 7 8 System.out.println(n); 9 10 name += "; The end."; // bug #2 main[1] print Buggy.name Buggy.name = null main[1] help ** command list ** threads [threadgroup] -- list threads thread <thread id> -- set default thread suspend [thread id(s)] -- suspend threads (default: all) resume [thread id(s)] -- resume threads (default: all) where [thread id] | all -- dump a thread's stack wherei [thread id] | all -- dump a thread's stack, with pc info threadgroups -- list threadgroups threadgroup <name> -- set current threadgroup print <id> [id(s)] -- print object or field dump <id> [id(s)] -- print all object information locals -- print all local variables in current stack frame classes -- list currently known classes methods <class id> -- list a class's methods stop in <class id>.<method>[(argument_type,...)] -- set a breakpoint in a method stop at <class id>:<line> -- set a breakpoint at a line up [n frames] -- move up a thread's stack down [n frames] -- move down a thread's stack clear <class id>.<method>[(argument_type,...)] -- clear a breakpoint in a method clear <class id>:<line> -- clear a breakpoint at a line step -- execute current line step up -- execute until the current method returns to its caller stepi -- execute current instruction next -- step one line (step OVER calls) cont -- continue execution from breakpoint catch <class id> -- break for the specified exception ignore <class id> -- ignore when the specified exception list [line number|method] -- print source code use [source file path] -- display or change the source path memory -- report memory usage gc -- free unused objects load classname -- load Java class to be debugged run <class> [args] -- start execution of a loaded Java class !! -- repeat last command help (or ?) -- list commands exit (or quit) -- exit debugger main[1] exit ian>
http://www.extremeprogramming.org) advocate
writing the unit tests before you write the
code, and they also advocate running your tests almost every time you
compile. This group of extremists has some very well-known leaders,
including Gamma and Beck of Design Patterns
fame. I definitely go along with their advocacy of unit testing.main
method that just tests out the
functionality of the class. Here is an
example:/** A simple class used to demonstrate unit testing. */
public class Person {
protected String fullName;
protected String firstName, lastName;
/** Construct a Person using his/her first+last names. */
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
/** Get the person's full name */
public String getFullName( ) {
if (fullName != null)
return fullName;
return firstName + " " + lastName;
}
/** Simple test program. */
public static void main(String[] argv) {
Person p = new Person("Ian", "Darwin");
String f = p.getFullName( );
if (!f.equals("Ian Darwin"))
throw new IllegalStateException("Name concatenation broken");
System.out.println("Fullname " + f + " looks good");
}
}catch
clause that matches it. If none is
found, the Java interpreter program that invoked your main(
) method catches the exception and prints a stack traceback
showing all the method calls that got from the top of the program to
the place where the exception was thrown. You can print this
traceback yourself in any catch clause: the
Throwable
class has several methods called
printStackTrace( ).javac, this is
the default. When using Ant's
javac task, this is not the default; you must be
sure you have used <javac
debug="true" ...> in your
build.xml file if you want line numbers.http://java.oreilly.com/). What I
didn't tell you, but what you might have realized by
extension, is that the source examples from all
the O'Reilly Java books are available there, too:
the examples from Java Examples in a Nutshell,
Java Swing—all of them.java.util.ArrayList actually works? You have the
source code. Got a problem making a JTable behave?
Sun's JDK includes the source for all the public
classes! Look for a file called
src.zip
or src.jar ; some
versions unzip this and some do not.java.io.Reader has a method
called read(
)
, which reads bytes of data from a file
or network connection. This is written in C because it actually calls
the read( ) system call for Unix, Windows, Mac OS,
BeOS, or whatever. The JDK source kit includes the source for all
this stuff.Debug utility mentioned in Recipe 1.11.package com.darwinsys.util;
/** Utilities for debugging
*/
public class Debug {
/** Static method to see if a given category of debugging is enabled.
* Enable by setting e.g., -Ddebug.fileio to debug file I/O operations.
* Use like this:<BR>
* if (Debug.isEnabled("fileio"))<BR>
* System.out.println("Starting to read file " + fileName);
*/
public static boolean isEnabled(String category) {
return System.getProperty("debug." + category) != null;
}
/** Static method to println a given message if the
* given category is enabled for debugging.
*/
public static void println(String category, String msg) {
if (isEnabled(category))
System.out.println(msg);
}
/** Same thing but for non-String objects (think of the other
* form as an optimization of this).
*/
public static void println(String category, Object stuff) {
println(category, stuff.toString( ));
}
}System class, which knows a lot about your
particular system.java.lang.Runtime
, lies behind many of the methods in the
System class. System.exit(
)
,
for example, just calls Runtime.exit(
)
. It is technically part of
"the environment," but the only
time we use it directly is to run other programs, which is covered in
Recipe 26.1. The
java.awt.Toolkit object is also part of the
environment and is discussed in Chapter 13.System class, which knows a lot about your
particular system.java.lang.Runtime
, lies behind many of the methods in the
System class. System.exit(
)
,
for example, just calls Runtime.exit(
)
. It is technically part of
"the environment," but the only
time we use it directly is to run other programs, which is covered in
Recipe 26.1. The
java.awt.Toolkit object is also part of the
environment and is discussed in Chapter 13.static method called getenv(
)
in class
java.lang.System . But remember, you made me do
it. First, the code. All we need is the little program shown in Example 2-1.public class GetEnv {
public static void main(String[] argv) {
System.out.println("System.getenv(\"PATH\") = " + System.getenv("PATH"));
}
}C:\javasrc>javac GetEnv.java
Note: GetEnv.java uses or overrides a deprecated API. Recompile with -deprecation for
details.C:\javasrc>javac -deprecation GetEnv.java
GetEnv.java:9: Note: The method java.lang.String getenv(java.lang.String) in class
java.lang.System has been deprecated.
System.out.println("System.getenv(\"PATH\") = " + System.getenv("PATH"));
^
Note: GetEnv.java uses or overrides a deprecated API. Please consult the
documentation for a better alternative.
1 warningSystem.getProperty(
)
or System.getProperties(
).java.util.Properties
object, which we discuss more fully in Recipe 7.7. So if I chose to, I could store the following
properties in a Properties object called
ian:name=Ian Darwin favorite_popsicle=cherry favorite_rock group=Fleetwood Mac favorite_programming_language=Java pencil color=green
Properties
class has several forms of its retrieval
method. You could, for example, say
ian.getProperty("pencil
color")
and get back the string "green".
You can also provide a default: say
ian.getProperty("pencil
color",
"black"), and, if the property has not been set,
you get the default value "black".System
class
and its role as keeper of the particular
Properties object that controls and describes the
Java runtime. The System class has a static
Properties member whose content is the merger of
operating system specifics
(os.name, for example), system and user tailoring
(java.class.path), and properties defined on the
command line (as we'll see in a moment). Note that
the use of periods in these names (like os.arch,
os.version, java.class.path,
and java.lang.version) makes it look as though
there is a hierarchical relationship similar to that for class names.
The Properties class, however, imposes no such
relationships: each key is just a string, and dots are not special.System.getProperty( ). If you want them all, use
System.getProperties( ). Accordingly, if I wanted
to find out if the System
Properties had a property named
"pencil color", I could say:String color = System.getProperty("pencil color");System.getProperty( ):System.out.println(System.getProperty("java.specification.version"));Class.forName("class")
, which throws an
exception if the class cannot be loaded—a good indication that
it's not present in the runtime's
library. Here is code for this, from an application wanting to find
out whether the JDK 1.1 or later components are avai