This page is on the Computer Science Department's WWW Server at CalState, San Bernardino, California, USA. It was generated by Doc Dick Botting.


Also see http://www.csci.csusb.edu/dick/se.html#Bibliographies.
From csus.edu!csulb.edu!drivel.ics.uci.edu!news.service.uci.edu!unogate!mvb.saic.com!news.mathworks.com!newsfeed.internetmci.com!portal.gmu.edu!hearst.acc.Virginia.EDU!news-server.ncren.net!concert!newz.oit.unc.edu!helios.oit.unc.edu!usenet Thu May 23 18:07:24 1996
Path: csus.edu!csulb.edu!drivel.ics.uci.edu!news.service.uci.edu!unogate!mvb.saic.com!news.mathworks.com!newsfeed.internetmci.com!portal.gmu.edu!hearst.acc.Virginia.EDU!news-server.ncren.net!concert!newz.oit.unc.edu!helios.oit.unc.edu!usenet
From: elharo@helios.oit.unc.edu (java FAQ)
Newsgroups: comp.lang.java

Subject: comp.lang.java FAQ

Followup-To: comp.lang.java
Date: 13 May 1996 17:46:31 -0400
Organization: Cafe Au Lait
Message-ID: <4n8ajn$870@helios.oit.unc.edu>
NNTP-Posting-Host: fddisunsite.oit.unc.edu
Status: O

Archive-name: computer-lang/java-faq/part1
Posting-Frequency: weekly
Last-modified: 1996/3/27
Version: 0.9.8
URL: http://sunsite.unc.edu/javafaq/javafaq.html

	       JAVA FAQ LIST AND TUTORIAL: A WORK IN PROGRESS
	                               
   This is the Java FAQ list. A Java Tutorial is being developed as
   simultaneously as time permits. If you already know C++, this FAQ list
   is probably the most useful. If you don't know C++ or C, you may want
   to go through the tutorial before delving into the later sections of
   this FAQ.
   
   If you're reading the text version via Usenet, I do apologize that
   parts of it may be less intelligible than possible in HTML. Please
   refer to the HTML version at
   http://sunsite.unc.edu/javafaq/javafaq.html.

[
 Dick says:
 I'm not allowed to show you mor than this.... see below
]
   This FAQ list and its entire contents are copyright 1995 by Elliotte
   Rusty Harold. If you have specific desires to republish it in whole or
   part contact me at elharo@sunsite.unc.edu and tell me exactly what you
   want to do. I'm generally receptive to non-profits that want to make
   it available to the public at no charge and to anyone who's willing to
   make reasonable payment arrangments.
   
   However I do not allow the FAQ list, either the text or HTML version,
   to be placed on any web sites but my own. Mirroring HTML files is a
   fundamentally bad idea that is at cross-purposes with the design of
   the web. Among other problems it makes maintaining up-to-date copies
   phenomenally difficult. If you think this file would be a useful
   addition to your web site, then link to it. That's the way the web is
   designed. Not all information needs to reside in one central location.
   No permission is needed to link to this or any other of my HTML files.
   In fact I'd prefer it if you'd not ask me, since then I don't have to
   spend time answering you.
   
   Although there's more reason to want to translate the document rather
   than merely mirror it, I regret that I do not have the time or
   resources to support any translation efforts. This document will be
   available in English only for the foreseeable future.
   
   
   
   
--   
   Copyright 1995 Elliotte Rusty Harold
   elharo@sunsite.unc.edu
   Last Modified March 27, 1996
-- 
Elliotte Rusty Harold     
elharo@sunsite.unc.edu    
elharo@shock.njit.edu 
[
 Blame him if his server gets overloaded:-)
]

From csus.edu!csulb.edu!awabi.library.ucla.edu!128.32.206.55!newsfeed.berkeley.edu!news2.best.com!news3.best.com!nntp1.ba.best.com!not-for-mail Thu Apr  1 15:23:15 1999
Path: csus.edu!csulb.edu!awabi.library.ucla.edu!128.32.206.55!newsfeed.berkeley.edu!news2.best.com!news3.best.com!nntp1.ba.best.com!not-for-mail
From: pvdl@best.com (Peter van der Linden)
Newsgroups: comp.lang.java.programmer,comp.lang.java.help,comp.lang.java.gui,comp.answers,news.answers

Subject: Java Programmers FAQ

Supersedes: <7ad87j$45c$1@shell15.ba.best.com>
Followup-To: poster
Date: 26 Mar 1999 11:47:55 -0800
Message-ID: <7dgo9b$1tp$1@shell15.ba.best.com>
Summary: This posting answers frequently-asked questions by Java programmers
NNTP-Posting-Host: shell15.ba.best.com
X-Trace: nntp1.ba.best.com 922477685 220 pvdl@206.184.139.147
Xref: csus.edu comp.lang.java.programmer:183884 comp.lang.java.help:39631 comp.lang.java.gui:24040 comp.answers:33596 news.answers:142121
Status: O

Archive-name: computer-lang/java/programmers/faq
Posting-Frequency: weekly
Last-modified: 1999/03/26
URL: http://www.afu.com/javafaq.html

Frequently Asked Questions (with answers) for Java programmers

	   _____________________________________________________
  ________|                                                     |________
  \       |   Java Programmers FAQ         http://www.afu.com   |       /
   \      |   Last modified Mar 26, 1999   Peter van der Linden |      /
   /      |_____________________________________________________|      \
  /___________)                                              (__________\

The Java FAQs here are intended for people who already have some programming
experience, though maybe not in Java.

Go to the FAQ home page at http://www.afu.com for other Java information and
downloads, and the most up-to-date copy of the FAQ. Report FAQ updates to
faqidea at the address afu.com.

------------------------------------------------------------------------

The sections of the Java FAQ are:

   * 1. Java Book Information
   * 2. Getting Started
   * 2.5 Portability
   * 3. General Information
   * 4. Compilers and Tools
   * 5. Compiler Messages
   * 6. Java Language issues
   * 7. I/O
   * 8. Core library issues
   * 9. Computer Dating
   * 10. AWT
   * 11. Swing
   * 12. Browsers
   * 13. Applets
   * 14. Multi-Media
   * 15. Networking
   * 16. Security
   * 17. For C, C++ Afficionados
   * 18. Java Idioms
   * 19. Java Gotcha's
   * 20. Further Resources
   * 21. Acknowledgements

	               -------------------------------

1. Java Book Information

  1. (sect. 1) How do I choose a Java book?

     [*] There is no one right answer to "which is the right Java book for
     me?"
     A lot depends on what you already know, and how you like to
     learn.
     If you already know how to program in another language, and Just want
     to learn Java, consider Just Java 1.2 from the FAQ author.

     Everything in one handy volume (language basics, Swing, networking,
     I/O, database access, etc) and it comes with a CD with tons of Java
     applets, games, applications, compiler tools, complete with source.
     Includes a Java compiler for Windows, the Mac, Linux, and Solaris
     (sparc and x86). look at http://www.amazon.com for details

      If you or your manager instead want a briefing on Java
      technology, thin clients, XML, CORBA, TCP/IP, Java beans,
      etc., take a look at Not Just Java from the FAQ author.
	                                                            [Image]
      This book doesn't teach you how to program in Java; it tells
      you why you might want to, and what kind of systems are most
      suited to Java. It describes E-Commerce and XML. look at
      http://www.amazon.com for details

     Sample chapters (from the previous editions -- must fix that) are on
     Sun Microsystems' webpage at http://www.sun.com/.
     Here are the points to check when evaluating a programming book.
	o Above all, make sure that it is a Java book. If it comes with a
	  CD, check that it has a Java compiler on it, not a J++ compiler.
	  J++ is a different language in some important ways, and is missing
	  several of the latest Java libraries (Swing, Collections, JFC,
	  RMI). J++ does not implement Java 2. If your interest is Java,
	  leave the downrev J++ book back on the shelf.
	o Does the book cover the current level of Java, which is Java 1.2
	  (aka Java 2)? Look up "JApplet" in the index. If it's not there
	  the book doesn't cover JDK 1.2, and you probably need a more
	  up-to-date book.
	o Check that the book has a reasonable number of figures, diagrams,
	  and illustrations. It is not possible to explain how to program a
	  window system without pictures and diagrams. Other topics benefit
	  from pictures, too.
	o Check what the book says about itself. Is it a reference work,
	  intended for Java-experts to look things up in? This is the role
	  of "Java in a Nutshell", and "The Java Almanac". Do you need that,
	  or are you looking for a book that teaches by examples and
	  explanations?
	o Read Peter Norvig's excellent advice on learning programming
	  languages and being a programmer.
	o Appraise your own level of programming knowledge: are you
	  proficient in some other language, or are you learning programming
	  as well? Does the book cater to your level?
	o Read a section of the book. Does the style keep you interested, as
	  it educates you? Will you get bored if you read many pages? Is the
	  book too long for your initial purpose? Browse Amazon online and
	  see what other readers say about the text.
	o If the book comes with a CD, how much other software is on the CD?
	  You want at least a Java compiler plus all the examples from the
	  book. Does the Java compiler work on your platform (Mac, Linux,
	  etc)? Additional software on the CD is a big plus, as we learn the
	  most from reading other people's code.

     Most people buy one book to begin with, then four or five more as they
     wish to learn more, and about more specialized topics. The FAQ author
     has purchased and read probably 60 Java books in the last three years.

  2. (sect. 1) Where can I find a some lists of Java books and book reviews?

     [*] Here are some good ones:
     http://www.geocities.com/RainForest/Canopy/4774/Java/education.html
     also
     http://www.flathill.com/languages/java/
     also
     http://www.fastgraph.com/books/java.html
     also
     http://teamjava.com/links/tj-srv.cgi?MUF=0,tj-booklist.muf
     also
     http://www.javaworld.com/javaworld/books/jw-books-index.html
     (an exhaustive list -- takes a long time to load).

	               -------------------------------

2. Getting Started

  1. (Sect. 2) What is the easiest way to get started with Java?

     [*] Follow these steps.
       1. Look at the books section of the FAQ to see what kind of book will
	  suit you. There is no one perfect Java book. The right book
	  depends on the style, pace, and detail that you are comfortable
	  with. Amazon has good info and reviews on Java books.

       2. Download a free Java compiler from http://java.sun.com

       3. Read the free Java tutorial, at
	  http://java.sun.com/docs/books/tutorial/index.html
	  (bookmark it, so you will easily find it again).

       4. Avoid Microsoft's J++ product, which is in the words of
	  Microsoft's own employees "polluted Java". It is designed to
	  undermine standard Java, and has many deliberate platform-specific
	  incompatibilities, including new keywords in the language.

       5. Search this FAQ when something in Java confuses you. Many people
	  have trodden this path before you, and the FAQ contains the
	  accumulated knowledge and pointers to other references.

  2. (Sect. 2) Why doesn't my "Hello World!" program compile?

     [*] There are three basic possibilities:
       1. Are you successfully running the javac compiler?
	  Try

	  javac -garbage

	  to see if it prints out a message about correct usage. If not,
	  invoke javac using the full pathname, or set your PATH variable to
	  include the directory that contains javac.
       2. Is the CLASSPATH environment variable used correctly?
	  In JDK 1.0.2, beginners had to set CLASSPATH, and it had to
	  include both system libraries and your programs.
	  In JDK 1.2, CLASSPATH is no longer needed for system libraries.
	  You do want CLASSPATH to point to the directories containing any
	  "user classes" you're using.
	  Getting started, you will probably want at a minimum "." (the
	  current directory) in your CLASSPATH.
	  When CLASSPATH is wrong, javac will tell you it can't find
	  definitions for classes you reference in the source file. For
	  information on setting up the CLASSPATH, see Question 1.3
       3. Is the source correct?
	  Here javac will emit error and warning messages. See the questions
	  on compiler messages in the next section.

  3. (Sect. 2) Why doesn't my "Hello World!" program run?

     [*] There are five common mistakes that cause your VM (java or browser)
     to be unable to execute your classes
       1. First, did you write an applet or an application? If an applet,
	  you must make sure that you did extend the java.applet.Applet
	  class. Your starting code should be in the init routine.
	  If you wrote an application, your starting code should be in a
	  routine called main(). Don't mix applets with applications until
	  you have a bit more experience.
       2. You must declare your main class as "public". If you don't,
	  unfortunately some systems will still run the code, while others
	  won't. The main class is either the one with the main() method in,
	  or in the case of an Applet, the class that extends Applet.
       3. Your class name and the file name must match exactly, even letter
	  case. If your class is HelloWorld, your source file must be
	  HelloWorld.java and your class file will be "HelloWorld.class".
       4. If an Applet, and you used ftp to transfer the classes to the
	  server, you must ftp all the classes, and you must use BINARY
	  transfer not ASCII.
       5. Errors in setting the CLASSPATH (and/or codebase in an applet).
	  Even seasoned programmers do this, pointing inside a package or
	  mistyping a path delimiter. For information on setting up the
	  CLASSPATH and codebase, see Question 1.3

     If you are running an applet, you should check the following further
     points:
       1. If your class isn't loading, recheck the HTML applet tag.
       2. If you are writing to System.out, the results are displayed in the
	  browser's java console. You'll have to create a window if you want
	  one.
       3. Make sure your browser is compatible with the Java language
	  features you are using. Internet Explorer and older versions of
	  Netscape's browsers have omitted some support for JDK 1.1. Try
	  your applet in the JDK's appletviewer first.

  4. How do I set the CLASSPATH?

     [*] The CLASSPATH environment variable tells the VM's class loader
     where to find classes that are directly or indirectly invoked,
     including system classes. The CLASSPATH variable should
	o point to the directory containing the class file, for classes not
	  in a package.
	o point to the package root, for classes in a package. The root is
	  the parent directory of the highest directory of the package name.
	o point directly to the zip or jar file, if the classes are in an
	  archive file. You may have to list the contents of the archive to
	  get the correct package/path name for the class.
	  Separate multiple paths and archives with a platform-specific
	  separator, ";" for Windows; ":" for Solaris
     Also remember that
	o Browsers set the CLASSPATH to the directory of the HTML file, plus
	  the codebase parameter.
	o in JDK 1.1 and after, java adds the system classes
	  (lib/classes.zip), so you don't have to.
	o JDK 1.2 versions of java add "." (current directory), so you don't
	  have to. (But jre doesn't - see below.)
	o JDK 1.1 jre tool does not use the CLASSPATH variable or assume the
	  current directory. (On Solaris, CLASSPATH does work.)

     From JDK 1.1.2 on, it is generally an error if the user sets the
     CLASSPATH to include classes.zip. But CLASSPATH will need to be set to
	o point to the roots of the programmer's own packages, and third
	  party packages
	o use rmic
	o use unbundled packages like Swing in JDK 1.1
	o point to native code libraries.

     For the sake of consistency, the minimal classpath setting should be: "
     set CLASSPATH=. "
     Below you'll find examples for Windows (basic application class),
     Solaris (package class), javac (multiple packages), and browsers
     (applet codebase).
     -----------------------------

     Here's some Windows examples, assuming the application class is

     D:\src\tries\HelloWorld.class

	     ## JDK 1.1,  no CLASSPATH set
	     > cd D:\src\tries\
	     > D:\jdk11\bin\java HelloWorld
	       # OK: 1.1 implicitly adds classes.zip and current dir

	     > D:\jdk11\bin\jre HelloWorld
	       # FAILS: jre does not automatically add . to CLASSPATH

	     > cd D:\
	     > D:\jdk11\bin\jre -cp D:\src\tries HelloWorld
	       # OK: jre adds classes.zip, -cp adds class directory

	     ## JDK 1.1,  CLASSPATH set
	     > set CLASSPATH=D:\src\tries
	     > D:\jdk11\bin\java HelloWorld
	       # OK: java using CLASSPATH

	     > D:\jdk11\bin\jre HelloWorld
	       # FAILS: jre does not use CLASSPATH (on Windows)

	     ## JDK 1.0.2,  CLASSPATH set
	     > set CLASSPATH=D:\jdk102\lib\classes.zip;D:\src\tries
	     > D:\jdk102\bin\java HelloWorld
	       # OK:

	     > set CLASSPATH=D:\jdk102\lib\classes.zip;D:\src\tries
	     > D:\jdk11\bin\java HelloWorld
	       # FAILS: exception in thread NULL - wrong system classes


     -----------------------------

     Here's some Solaris examples, assuming the application class is

     /usr/src/com/devjoes/killer/App.class

     and it is in package com.devjoes.killer:

	     # JDK 1.1, no CLASSPATH set
	     $ /usr/bin/jdk11/bin/jre  -cp /usr/src   com.devjoes.killer.App
	       # OK:

	     $ cd /usr/src/com/devjoes/killer/
	     $ /usr/bin/jdk11/bin/java App
	       # fails: class name and path are wrong

	     $ CLASSPATH=/usr/src/
	     $ /usr/bin/jdk11/bin/java App
	       # fails: class name is com.devjoes.killer.App

	     $ /usr/bin/jdk11/bin/java com.devjoes.killer.App
	       # OK:


     -----------------------------

     Here's some javac examples, for both Solaris and Windows, based on the
     following:
      Source files                package           Makes the call
      /usr/src/pack/Minimal.java  package pack      pack.sub.Try.run()
      /usr/src/pack/sub/Try.java  package pack.sub  (nothing)

	     $ CLASSPATH=""
	     $ /usr/bin/jdk11/bin/javac /usr/src/pack/sub/Try.java
	       # OK: works fine

	     $ /usr/bin/jdk11/bin/javac /usr/src/pack/Minimal.java
	       # FAILS: can't find pack.sub.Try

	     $ cd /usr/src
	     $ /usr/bin/jdk10/bin/javac pack/Minimal.java
	       # OK: finds pack.sub.Try based on . as package root

	     $ cd /usr/src/pack
	     $ CLASSPATH=/usr/src
	     $ /usr/bin/jdk11/bin/javac Minimal.java
	       # OK: finds pack.sub.Try based on CLASSPATH


     Now assume the killer application class

     /usr/src/com/devjoes/killer/FastApp.java

     (in package com.devjoes.killer) uses a third-party package in a jar
     file

     /usr/jars/JShapes.jar

     but makes no other reference to other classes. The following works
     fine:

	     $ CLASSPATH=/usr/jars/JShapes.jar
	     $ cd /usr/src/com/devjoes
	     $ /usr/bin/jdk11/bin/javac killer/FastApp.java


     Finally, some applet examples. Many applets only use one class, in the
     same directory as the html file:

     


     To use classes in subdirectory, use the codebase parameter:

     http://java.sun.com/products/jdk/1.2/changes.html#aaa24

	                  -----------------------------

     Specify standard Java on your new PC!

	     Your new PC can come with the most up-to-date standard version
	     of Java, but only if you ask for it! The JavaLobby is asking PC
     vendors to support Java, and to ship new machines with the Java Plug-In
     pre-installed.

     See http://www.javalobby.org/servlet/PetitionServlet/pjpc
     Please help the Java Lobby to promote this initiative.

     -----------------------------------------------------------------------

     Please support Java Portability.

     The biggest value of Java is its portability.
	o Portability makes it easier for companies to change/upgrade
	  operating systems and platforms, without losing their investment
	  in applications software.
	o Portability makes it easier for Java programmers to transfer their
	  skills to new employers.
	o Portability makes a wider variety of software available on all
	  computers.
     Software portability is very much in the interest of most software
     developers and customers. Even if you only use Windows 95, portability
     matters to you. If your software was all written in Java, it would all
     just run when you moved from MS-DOS to Windows 3.1 to Windows 95 to
     Windows 98 to Windows NT, and even on Windows CE. Instead, you
     typically need to buy new applications software all over again when
     Windows changes. Portability is not in Microsoft's interest, as it
     removes a revenue stream and makes it easy for users to try other
     operating systems.

     The 1998 anti-monopoly case against Microsoft revealed a Microsoft
     internal memo. The memo stated that Microsoft's "strategic objective"
     was to "kill cross-platform Java." by grow[ing] the polluted Java
     market." This is Exhibit 101 (MS7 033448) in the case.

     In November 1998, a Federal judge ruled that Microsoft was probably
     breaking its written agreement with Sun by distributing incompatible
     Java, and that Microsoft had to stop doing that. If portability matters
     to you or your users, avoid Java products from Microsoft; it is
     deliberately trying to sabotage it. Microsoft's own internal documents
     make this goal unambiguous. See
     http://www.usdoj.gov/atr/cases/f1700/1762.htm.

	                  -----------------------------

     Windows-Specific

 17. Is there a Java implementation for Windows 3.1?

     [*] Yes. See Question 1.6 It's not that great though because Windows
     3.1 has inadequate features to support great software.

 18. (Sect. 2) I'm using Win95, and my DOS window won't accept filenames
     longer than 8.3.
     "This program cannot be run in DOS mode"

     [*] Both these problems are resolved by the same process. Assuming
     you're running the Win95/98 command.com, then you've changed the MS-DOS
     Prompt options under the "Properties" menu item. In the Properties
     dialog, Program->Advanced gets you a dialog. Here, make sure the
     "Prevent MS-DOS-based programs from detecting Windows" checkbox is
     UNCHECKED.

     If the option is checked you get exactly the kind of behavior you're
     seeing. The option is unchecked by default, so it must have been
     selected at some time in the past. Change it back to unchecked.

 19. (Sect. 2) I'm using Notepad to edit my files, and how can I save them
     with the extension ".java"? Also, in notepad some source files have all
     the characters on one line. Why is that?

     [*] First answer: put the entire filename in quotes in the save dialog.
     Once you have created your first Java file, double click on it in
     Explorer, select "Notepad" from the "Open with" box, and Notepad will
     stop adding the spurious ".txt" to your .java files.

     Second answer: Notepad expects to see a "carriage return/line feed"
     pair at the end of each line, rather than just the "newline"
     (line-feed) commonly used on Unix. Use this program to expand all
     newlines,

     /*
      * Usage: jre crlf file1.java file2.java ... fileN.java
       */

     import java.io.*;
     class crlf {
	 public static void main(String s[]){
	     byte b[]; byte p;
	     FileInputStream is;
	     BufferedOutputStream os;
	     File f;
	     for (int i=0; i < s.length;i++){
	         try{
	             f=new File(s[i]);
	             b=new byte[(int)f.length()];
	             is = new FileInputStream(f);
	             is.read(b); is.close();
	             os = new BufferedOutputStream(
	             new FileOutputStream(s[i]),b.length);
	             p='?';
	             for(int j=0; j < b.length; j++){
	                 if((p!='\r')&&(b[j]=='\n')) os.write('\r');
	                 p=b[j]; os.write(p);
	             }
	             os.flush(); os.close();
	         }catch(IOException e){
	             System.err.println(e.toString());
	         }
	     }
	 }
     }


     The source code is to show new users a way to make a simple program
     which can read a file and write it out buffered.

     Compile with "javac crlf.java" and run with
     java crlf outfile.txt
     or just use Wordpad instead of Notepad. Wordpad is under
     Start->Programs->Accessories->WordPad

 20. (Sect. 2) How do I fix the message about "out of environment variable
     space"?

     [*] This occurs under Windows when you have long CLASSPATH names. You
     need to increase the environment space. On Windows 95,8 put this in
     your c:\windows\system.ini

	     [NonWindowsApp]
	     CommandEnvSize=4096


     On NT you can right-click on My Computer, select System Properties then
     go to the Environment tab and then increase COMSPEC to the value you
     want.

     The previous suggestion to put this in your config.sys:

	     shell=command /e:4096


     apparently causes you to create two copies of command.com which wastes
     memory.

	               -------------------------------

3. General Information

  1. (Sect. 3) Is Java "Open" or "Proprietary"?

     [*] The Java specification is publicly available, and anyone is free to
     do clean-room implementations of the JVM and core Java API's. Sun
     includes a perpetual, irrevocable, free and royalty-free license in the
     front of the Addison-Wesley books containing the specification.

     Sun also provides free access to the Java source. See
     http://java.sun.com/communitysource/

     Using the Java trademark does requires licensing from Sun. It is not
     clear if the Embedded or Personal Java specifications are open, as it
     is not clear if a clean-room implementation may be done without
     licensing from Sun.

     The relative openness of Java contrasts with systems that are only
     available from one vendor, whose interfaces are developed in secret,
     without an open process for others to participate, whose owners do not
     allow competing implementations of the same API, and whose owners
     change the APIs as a strategic weapon against competitors. Typically,
     such systems also feature "private" APIs that are published late or not
     published at all, to allow the single vendor to gain a competitive
     advantage for their other products. Typically such proprietary systems
     do not make the source code available for inspection by all.

  2. (Sect. 3) What is the best way to refer someone to the FAQ when they
     ask a question I know is answered there?

     [*] The Java Programmers FAQ (at http://www.afu.com) answers your
     question in section N.n. ...

     This gives them the answer, and shows them where to go for future
     questions. It also demonstrates that the FAQ can answer their
     questions, supplying an incentive to go there next time. It's regarded
     as elementary politeness to look for the FAQ of a newsgroup and read it
     before posting any questions.

     In general, FAQs for any newsgroup are available by looking at past
     postings in a group, or by searching Deja News (see Q 1.4), or via
     anonymous FTP at directories under ftp://rtfm.mit.edu. The pathnames
     are called things like
     /pub/usenet-by-group/comp.lang.java.programmer/Java_Programmers_FAQ
     which may help you get to the right one directly, as it takes some time
     to get a directory listing there. Alternatively, you can look for
     newsgroup names on the same ftp site by going to the same site and
     looking under /pub/usenet-by-hierarchy/. That has subdirectories such
     as alt/, ba/, ca/, comp/, and subdirectories under them such as
     /pub/usenet-by-hierarchy/comp/lang/ and so on. This helps you explore
     the world of newsgroups with FAQs.

     If you do not have anonymous FTP access, you can access the
     rtfm.mit.edu archives by mail server as well. Send an E-mail message to
     mail-server@rtfm.mit.edu with "help" in the body for more information.
     "RTFM" stands for "Read The effing Manual" - you must expect to put in
     some time and effort to master a new area of study.

     If you want to look at the definition of Internet standards like FTP,
     telnet, visit the IETF site at http://www.ietf.org where all the RFC's
     (Request For Comments) can be found.

  3. (Sect. 3) What if my question is not answered in this FAQ?

     [*] Go to http://www.dejanews.com/home_ps.shtml
	o Under "Newsgroups" enter "comp.lang.java.programmer" (or whatever)
	o Under "Subject" enter "Frotteur" (or other topic you find
	  pressing)
	o Click "Create Filter"
	o It will go to a new document, and you should click the link
	  labeled

	  nnn Documents (nnn is some number).

     The chances are that you will find several answers to your question.
     Some may not be complete or completely accurate however. That is the
     nature of Usenet, and free information. If you still don't have an
     answer, then post your question on the most appropriate of the
     newsgroups. Don't spam the newsgroups by posting to multiple groups.
     Knowledgeable posters tend to ignore questions like that.

     Also look at http://sunsite.unc.edu/java/cgi-bin/query
     and look at http://asknpac.npac.syr.edu/ for a Java newsgroup search.

     http://www.javaworld.com/search.html can search the Javaworld
     newspaper.

  4. (Sect. 3) What Java mailing lists are there?

     [*] There are quite a few Java mailing lists.
     http://java.miningco.com/msub7.htm has a comprehensive list.

  5. (Sect. 3) Where can I look at the definitive Java Language
     Specification?

     [*] This is available online at:
	  http://java.sun.com/docs/books/jls/html/index.html (Java 1.0)

     and the Java 1.1 inner classes document at:
	  http://java.sun.com/products/jdk/1.1/docs/guide/innerclasses/
	  spec/innerclasses.doc.html

     and the other Java 1.1 update at:
	  http://java.sun.com/docs/books/jls/html/1.1Update.html

     and the Java API is at:
	  http://java.sun.com/products/jdk/1.1/docs/api

     It is also available as a book in printed form (details at website).
     Also see the "Clarifications and Amendments"
     http://java.sun.com/docs/books/jls/clarify.html.

     You can also see the virtual machine (execution environment)
     specification at
     http://docs.sun.com:80/ab2/coll.127.1/@Ab2CollToc?subject=java

  6. (Sect. 3) Where can I find information about future Java APIs?

     [*] JavaSoft has followed a policy of creating new APIs in consultation
     with leading industry participants, then posting the draft
     specification for public review and comments. Check the JavaSoft
     roadmap of new APIs and products at
     http://java.sun.com:80/products/api-overview/index.html
     Also, some APIs that are under consideration, possibly for JDK 1.2 are
     at:
	  http://java.sun.com/products/jdk/preview/docs/

  7. (Sect. 3) I'm looking for a Java style guide on naming conventions.

     [*] Check out the section "Naming Conventions" in the language
     specification
	  http://java.sun.com/docs/books/jls/html/6.doc.html#11186

     Also take a look at Doug Lea's draft coding standard -
	  http://gee.cs.oswego.edu/dl/html/javaCodingStd.html

     See also naming conventions for some basic rules of thumb.

  8. (Sect. 3) How do I check on known bugs in the JDK?

     [*] Look at the Java Developer Connection at http://java.sun.com/jdc.

     All the Java bugs that Sun knows about are listed there, with the
     exception of security-related bugs. The legal department in Sun vetoed
     the open publication of security bugs. After you have checked that the
     bug is not already listed, you can submit a bug report through:
     http://java.sun.com:80/cgi-bin/bugreport.cgi
     You should check that the bug doesn't already exist for two reasons:
     first, you might find the bug with a workaround listed. Second, you
     don't want to waste everyone's time with a duplicate bug report.

     You can also send in an RFE (Request For Enhancement) or ease-of-use
     issue there. You can even vote on the priority you would assign to a
     particular bug fix! Join the Java Developer Connection (it's free) by
     going to http://java.sun.com/jdc. Then browse
     http://developer.javasoft.com/developer/bugParade/#votes

  9. (Sect. 3) What computers have Java ports? Is there a port to Win 3.1?

     [*] A partial list of JDK ports is available from
     http://java.sun.com/cgi-bin/java-ports.cgi
     An (impressive) list of the systems that the GPL Kaffee JVM runs on is
     at http://www.transvirtual.com/ports.html

     There are several Java ports to Win 3.1. IBM's ADK1.02 is available at
     the following locations:
	o http://ncc.hursley.ibm.com/javainfo/latest/answers/faq0.html
	o http://www.alphaworks.ibm.com/formula
     IBM offers a port to Linux, as do others. The IBM Jikes port is at
     http://www.alphaworks.ibm.com/ There is a large amount of useful
     software there, including a profiling tool called jinsight.

     Netscape Navigator for Win3.1 has Java support. Java will never be
     well-supported under Win3.1 because Win3.1 lacks the basic features
     expected of a modern OS (primarily lengthy filenames and multithreading
     support).

     Also take a look at JavaSoft's JavaPC kit that can switch a PC into a
     thin client Java system (and back to Win3.1/DOS when you want). It's
     meant for software OEMs and large corporations running lots of older
     PCs, but you can use it on the latest Pentium II too. Details are at
     http://java.sun.com/products/javapc/index.html. JavaPC is available now
     for $100, runs on 486's with 8Mb or more Unlike the 16-bit versions of
     Netscape Navigator and Microsoft Internet Explorer, which provide a
     Java Virtual Machine that is only compliant with the JDK 1.0.2 API, the
     JavaPC software allows IS managers to deploy JDK 1.1-compatible Java
     applications on PCs running DOS and Windows 3.x.

 10. (Sect. 3) Where can I find information on Java 3D?

     [*] The Java 3D FAQ at http://tintoy.ncsa.uiuc.edu/~srp/java3d/faq.html
     may have the answers you're looking for. It contains general
     information about Java 3D, as well as programming tips.

 11. (Sect. 3) Where can I find information about Java Certification?

     [*] Sun is sponsoring an examination which programmers worldwide can
     take. Those passing can use the designation "Sun Certified Java
     Programmer". There is also a second-level test, involving writing a
     program to spec, and taking a further test. That results in the
     qualification "Sun Certified Java Developer". You can find out all
     about the exam at:
	  http://www.sun.com/service/suned/

     and then search for "sun certified java". It costs $150 to sit the Java
     Programmer exam. It is not trivial to pass the Java certification exam.
     It requires understanding the objectives of the test, and the material
     that is tested for. These are given, along with sample questions, at
     the URL mentioned above.

     There is a Java certification FAQ at: http://www.marcusgreen.co.uk

 12. (Sect. 3) How can I find links to recent news about Java?

     [*] This site contains links to late-breaking online news stories about
     Java. http://www.intelligence.com/java/
     Another good Java news source is http://www.nikos.com/javatoys.

     This site is a fine site for programmers who want to be well-informed
     about computer industry topics. It has a lot of coverage of Linux as
     well as more general news. http://slashdot.org Highly recommended.

     This site is a source of independent news and commentary on the
     computer industry, including Java. http://www.pjprimer.com/media.html.
     You have to subscribe ($10/year, 30 day free trial).

 13. (Sect. 3) What are the folks at GNU doing with Java?

     [*] First note that the URLs in this section change quickly, and soon
     become outdated. If you have an update, send it in. There is a Gnu Java
     page at http://www.gnu.org/software/java/java.html
     Guava (a GPL'd Java compiler) can be found at
	  ftp://ftp.yggdrasil.com/pub/dist/devel/compilers/guavac/
     Alternatively, it may be available at
     http://http.cs.berkeley.edu/~engberg/guavac
     Work is progressing on the Cygnus Java frontend to gcc. See
     http://www.cygnus.com/product/javalang/

     Kaffe (a JVM) can be found at
	  http://www.transvirtual.com This is Tim Wilkenson's company
	  devoted to commercializing the Kaffe JVM for the embedded systems
	  market. He also releases a version of it under the GPL. It also
	  comes with a the beginnings of a class library and the Pizza
	  compiler.

     Classpath is a free implementation of Sun's Java libraries (v1.1),
     being developed for the GNU Project ( http://www.gnu.org). Information
     regarding classpath is at http://www.classpath.org They aim to develop
     a 100% free drop in replacement for Sun's class libraries, targeting
     first the Japhar JVM (below). They are always looking for help, so feel
     free to stop by and volunteer.

     See also http://www.japhar.org This is the Hungry Programmer's JVM.
     Currently it is development grade only.

 14. (Sect. 3) What is "San Francisco"?

     [*] San Francisco is the code name for a very large Java project led by
     IBM, and involving other companies. The project is to provide a Java
     framework for data processing applications. A large number of classes
     are provided for general ledger, sales order, inventory management,
     etc., and these classes can be extended and customized for particular
     industries (vertical markets). It is a large and ambitious software
     project.

     IBM's SF project competes with products from companies like SAP and
     Baan. Of course, the SF project is multi-platform and uses Java beans
     and GUI interfaces. More information on SF is available at
     http://www.ibm.com/Java/Sanfrancisco

 15. (Sect. 3) What large Office-style or other applications have been
     written in Java?

     [*] Well, the first one to consider is IBM's San Francisco project,
     mentioned above. There is also Lotus's e-suite - a suite of Java
     applets and beans including a spreadsheet and a word processor. See
     http://esuite.lotus.com. These became available in March 1998.

     Another office suite in Java is Applix Anyware at
     http://www.applix.com/anyware/index.htm. Applix became available in
     downloadable demo form in April 1998.

     Yet another is Star Division's Client/Server Office. It is an office
     suite with the client part written in Java and able to run on
     JavaStations. The server part will run on Solaris, NT, OS/390, and
     AS/400. The older (non-Java) version is bundled with all Sun
     workstations sold in Germany. The Linux version is freely downloadable
     from http://www.stardivision.com.

     Another is Digital Harbor's Wav word processor. It supports component
     software, and it runs in 1MB, not the 114Mb of the latest MS Word. A
     free trial is avilable. See: http://www.digitalharbor.com

     Another Java application is Formula One for Java, an Excel-compatible
     spreadsheet written in 100% pure Java, and available for all systems
     that support Java. It runs as a Java Bean, so can easily be assembled
     as one component of a larger system. It also runs as an application,
     and as an applet! Formula One is a product of Visual Components, Inc.
     See http://www.f1j.com.

     Another one is Ncode Research Inc. who write Java viewers for office
     suites. They are file-format specialists. Their mission is to make all
     popular file formats available for the Java platform. They write 100%
     Pure Java viewers for Word, Excel and PowerPoint (including Office 95
     and 97 formats). See http://www.ncode.com/
     Another company operating in the same space is JSoft, at
     http://www.jsoftinc.com

     Intentia, the 8th largest ERP vendor (annual sales of $320 million),
     has moved their entire suite of applications (Movex - covering 8
     markets) from RPG to Java - 20 million lines worth. See their press
     release.

     The niche for single-user office productivity applications is pretty
     well already dominated by Microsoft products, and it is unrealistic to
     think that Java software will unseat shrink-wrapped software simply
     because it is written in Java. This is why Corel replanned its Java
     rewrite of Corel Office before taking it to FCS. When Corel did that,
     it also increased its investment in Java from 33% of R&D budget to 50%,
     at the expense of Windows.

     Most of Java development is taking place for custom applications
     internal to a company. Most programmers of any kind have never worked
     on MS Office, but work on internal applications, and so it is with
     Java. These projects don't have the high profile of major vendors'
     products, but they are the mainstay of the industry. There are many
     companies working on Java Beans, like http://www.quadbase.com who have
     Java graphing software. EspressChart is a Java Bean that gives you the
     ability to add 2D and 3D graphs in your applications/applets. This bean
     is easy to use, 100% Java, and runs anywhere.

     There are some excellent Java games applets at
     http://www.javaarcade.com Check out the pinball -- dig that crazy
     rhythm, man.
     There are more good Java games applets at
     http://www.frontiernet.net/~imaging/java_games.html
     If you want to use Java to learn math & computer graphics, visit
     http://www.frontiernet.net/~imaging/math_is_a_game.html

     ObjectDesign Inc., has an ODBMS written in 100% java. The product is
     named PSE Pro for Java. See http://www.objectdesign.com
     Another database written in Java is available from
     http://www.cloudscape.com.
     Another database written in Java is available from
     http://www.instantdb.co.uk. InstantDB is available free to
     non-commercial organizations, and is very well documented and
     maintained.
     Finally, note that Sun's Java compiler is written in Java. This is a
     really big application in widespread use on millions of platforms. The
     compile command "javac test.java" is equivalent to

	 java sun.tools.javac.Main test.java


     javac has a script wrapper just to set the heap size as a command line
     argument, as you can do in your own programs.

 16. (Sect 3.) What Java User Groups are there?

     [*] There are scores of Java User groups around the world, mostly in
     urban areas, and centers of software technology development. A partial
     list with contact information can be found at
     http://sunsite.unc.edu/javafaq/usergroups.html.

     If you can't find a user group in your area/school, it's easy and
     satisfying to start one.

 17. (Sect 3.) What is a Java Bean?

     [*] A Java bean is a Java class that follows some simple conventions.
     Because it follows conventions, it can easily be processed by a
     software tool that connects Beans together at runtime. Java beans are
     reusable software components.

     Think of Java beans as being the software equivalent of Lego[tm]
     bricks. Instead of plugging together plastic bricks, you can easily
     plug together classes, and have them fit and work with each other. See
     http://www.jc100.org/
     See the Java Bean FAQ at http://java.sun.com/beans/faq/faq.general.html

 18. (Sect 3.) Where can I find examples of the use of the Java class
     libraries?

     published by Addison Wesley, have extensive examples of how to use the
     standard libraries. One programmer comments "When I need to use an
     unfamiliar area of the class libraries one of the first things I do is
     read their examples." You can see them online at
     http://java.sun.com/docs/books/chanlee/second_edition/vol1/examples.html
     and http://java.sun.com/docs/books/chanlee/second_edition/examples.html

 19. (Sect 3.) How can I find out exactly what version of Java I have on my
     system?

     [*] On a Solaris system, you can use the pkginfo command, like this:

	pkginfo -l SUNWjvrt

     It will give a reply like this:

	PKGINST:  SUNWjvrt
	   NAME:  JavaVM run time environment
       CATEGORY:  system
	   ARCH:  sparc
	VERSION:  1.1.6,REV=1998.07.30.16.21
	BASEDIR:  /
	 VENDOR:  Sun Microsystems, Inc.
      ...etc

     You may also try

	java -fullversion

     Although that's not an officially-supported command option, and has
     gone away in JDK 1.2. Try also

	java -version

	               -------------------------------

4. Compilers and Tools

  1. (Sect. 4) Is there a lex and yacc or preferably a flex and bison
     equivalent for Java?

     [*] There is a lex equivalent called JavaLex and a yacc equivalent
     called CUP.

     LALR(1) parser JavaLex and JavaCup:
     http://www.cs.princeton.edu/~appel/modern/java/

     LL(k) parser JavaCC: http://www.suntest.com/JavaCC/
     LALR(1) parser SableCC from McGill U.
     http://www.sable.mcgill.ca/sablecc/index.html is generously made
     available under GNU license.

  2. (Sect. 4) Where can I find a byte code obfuscator?

     [*] Java Obfuscators replace the original class, field and methods
     names in the bytecode with meaningless strings. Second generation
     obfuscators are now appearing that also obfuscate the control flow and
     encrypt String literals. People use obfuscators on their applets if
     they want to hide their code from others. Generally, you wouldn't do
     this with software that you put on your website for others to enjoy. It
     runs counter to the "open source" philosophy of learning from other's
     code and allowing them to learn from yours.

     Zelix KlassMaster is a commercially supported obfuscator. It has a free
     evaluation version at http://www.zelix.com/klassmaster
     Another commercially supported obfuscator, with a downloadable free
     trial is at http://www.4thpass.com/SourceGuard. There are also some
     free works from students and others. http://www.primenet.com/~ej/
     http://www.math.gatech.edu/~mladue/HoseMocha.java

     Some people have reported problems using these with JDK 1.1.

     This obfuscator has been updated to be fully compatible with JDK 1.1:
     http://www.monmouth.com/~neil/Obfuscate.html

     Obfuscators are intended to foil decompilers. Decompilers translate
     byte code back into Java source code. Mocha was the first and most well
     known of the decompilers; it's no longer supported. There is a
     decompiler (written in C++) at
	  http://www.geocities.com/SiliconValley/Bridge/8617/jad.html
     Because it is in C++, there are different versions for every
     architecture (hah!) There are also commercial products, such as
     SourceAgain from
	  http://www.ahpah.com/

     There's a very good Java Code Engineering and Reverse Engineering FAQ
     page at http://www.meurrens.org/ip-Links/Java/codeEngineering/.

  3. (Sect. 4) Which program is used to create .zip files compatible with
     the java* programs?
     (e.g. classes.zip, moz3_0.zip)

     [*] Use the jar-tool from JDK1.1(.1):
	  jar [ options ] [manifest] destination input-file [input-files]

     E.g.:
	  jar cvf myJarFile.jar *.class

     creates a compressed archive. And watch out -- the order of the options
     ("cvf") determine the order of the arguments!
	  jar cvfO myJarFile.zip *.class

     creates it fullsize (uncompressed) (note the 'O'-option used for
     JDK1.0.2)

     On Unix you can also use:
	  zip -rn ".class" my_file.zip *

     Info-ZIP home page: http://www.cdrom.com/pub/infozip/
     Latest source code: ftp://ftp.uu.net/pub/archiving/zip/src/zip21.zip

     Netscape's command line version of its JAR packager and signing tool is
     called "zigbert". They also have a signing tool with GUI written in
     Java. More info
     http://developer.netscape.com/software/signedobj/jarpack.html

     If you zip your .class files for JDK 1.0.2 (for 1.1 you'll use a Jar):
       1. zip your files uncompressed (can use WinZip 6.2 up);
	       Unix command:

	       zip -r0 classes.zip 

       2. Make sure the main class has no parent directory inside the
	  archive, (in other words, don't build an archive with
	  foo/bar/myMain.class, unless your myMain is in a package called
	  foo.bar. Instead start it at myMain.class). Your packages must be
	  placed in the archive using their corresponding filesystem
	  pathnames.
       3. Put the archive in the same directory as the .html page.
       4. Put something like the following tag in the .html file:

	  
	      


     From JDK 1.1 on, an example of the applet tag used with a jar file is

     
	     


     These lines will use an applet called myapplet that can be found in the
     jarfile myfile.jar. An example applet tag of a jar file used to hold
     classes in packages is

     
	     


     You can supply several jar filenames in a comma-separated list. Jar
     files are in compressed PKZIP format.

  4. (Sect. 4) Can I compile a Java program to a binary executable, .exe on
     a PC?

     [*] Compiling into native code destroys portability, which is one of
     the main benefits of Java. If you want to create a native executable
     because you wanted to make it easy to distribute and use programs,
     consider a Jar file instead.
     Some companies make products that do this. See the webpages for
     Symantec http://www.symantec.com, Supercede http://www.supercede.com,
     and Tower Technology http://www.twr.com. The first two are targeted to
     Windows. Tower Technology supports several flavors of Unix.

     Also, there is a native Java compiler from IBM, known as the HPJ (High
     Performance Java) compiler. One user has reported that it created a 2Mb
     executable from a 12K java file, and did not run any faster. See
     http://www.alphaworks.ibm.com/

     See also Instantiations JOVE http://www.instantiations.com/jove.htm,
     the paper about the Toba project
     http://research.microsoft.com/research/lt/toddpro/papers/coots97.pdf,
     Network World, "Vendors Rush To Speed Java Performance", Feb 9 1998, at
     http://www.nwfusion.com/news/0209java.html

     Compiling to native code takes away the most significant benefit of
     Java: portability of executables. Further, if you want your Java DLL
     (or .exe) to interact with C++, you'll have to specify which specific
     C++ compiler and/or actually compile some sort of linkage via the
     appropriate C++ compiler. C++ does not have a standard ABI, so there is
     a big problem with interoperability. Every C++ compiler uses a
     different object model, a different way of laying out class members,
     and a different way of "mangling" names for the linker.

     C is much simpler. The only question here is how structures are
     "packed" (i.e., are integers aligned on four-byte bounds?). All the C++
     compilers can interact with C code, thanks to 'extern "C"'
     declarations.

     Consider carefully why you want to compile to a native executable, and
     whether there is a Java way to accomplish your goal. There may be a
     good reason for compiling to native code, but it needs to be thought
     through.

  5. (Sect. 4) How can I performance profile my Java code?

     [*]java -prof MyClass

     produces some basic output in a file called java.prof, showing the
     number of times methods were invoked. The output lines are of the form:
	  # of calls     method called      called by        time spent
     On a Unix system, you can sort the file with something like

     sort -r +82  java.sort

     More and better Java tools are a third party opportunity. One Java
     profiler is JProbe Profiler, available from http://www.klg.com/jprobe.
     JProbe is said to be easy to use. Another profiler is OptimizeIt,
     available from http://www.optimizeit.com. Each of these profilers has
     performance tuning, which shows which methods took how much time, and
     also memory tuning, which shows what objects are in memory and how they
     were allocated. Both are important things to know. The latest version
     of the CodeWarrior IDE http://www.metrowerks.com has a time-based
     profiler for Java code. Java Workshop from Sun also has a time-based
     profiler.

     JDK 1.2 comes with some limited profiling capability built-in.
     Depending on your needs, it may be all that you need. Execute the
     following to get a short summary of what you can do:

	java -Xrunhprof:help

     For example, you can see which methods are taking the most time to
     execute, in the context of particular stack traces.

  6. (Sect. 4) When I use javadoc and I click on any java class included in
     the JDK why do I get this message?

	 Netscape is unable to find the file or directory named:
	 /E|/Jwrkshop/JDK/bin/java.lang.Throwable.html


     [*] References to the JDK classes assume that all generated html files
     are in the same directory and, in fact, that all files for all classes
     referenced are generated at the same time. There is no way to generate
     files incrementally and have them all reference each other, as you
     would like.

     As long as you have source for everything involved (including the JDK
     and all third-party classes), you can list all of your packages and all
     of the others on the javadoc command line and generate the whole set at
     once, but it is burdensome. Of course, if you receive any libraries as
     .class files, even this workaround will not suffice.

     Also javadoc will not generate the image files - you need to get them
     from the images directory under the JDK API documentation files. You
     can just copy the entire directory into your own doc directory. javadoc
     is a very nice concept, with a few implementation flaws.

  7. (Sect. 4) I'm working on a project with lots of classes and I use the
     JDK. A recompile from scratch takes forever when I do it a class at a
     time. How do I recompile everything?

     [*] The first way is
	  javac *.java

     Another way is
	  javac -depend tip.java

     where "tip.java" is a class "at the tip of the iceberg", i.e. that
     depends on (uses) all the other classes. Typically, this may be your
     main class. However, "-depend" is known to be buggy and cannot be
     relied upon. It also doesn't issue compile commands in parallel to make
     use of multi-processor systems.

     Without the "-depend" option, the standard "javac files" doesn't look
     beyond the immediately adjacent dependencies to find classes lower down
     the hierarchy where the source has changed.

     The -depend options searches recursively for depending classes and
     recompiles it. This option doesn't help when you have dynamically
     loaded classes whose names cannot be determined by the compiler from
     the dependency graph. E.g. you use something like
	  Class.forName(argv[0]);

     The author of the code using those classes should make sure that those
     classes are mentioned in a Makefile.

  8. (Sect. 4) Why do I get the java.lang.UnsatisfiedLinkError when I run my
     Java program containing Native Method invocations?

     [*] Your program is not able to find your shared library or DLL.

     On Windows 95/NT, make sure that the DLL exists in a path that is
     included within the PATH environment variable. (This need is true for
     both standard (untrusted) applications and trusted applets. At least,
     if you use the Java Plug-in to give yourself standard Java inside a
     browser).

     On Solaris, make sure that the environment variable LD_LIBRARY_PATH
     includes the path of your shared library.

     Note that jdb looks for libraries with "_g" appended to their names.
     Thus, if you intend to use jdb on a Java application that invokes
     native methods, you must ensure that the appropriately named libraries
     are in jdb's path. The "debug" nm libraries can simply be renamed
     copies of the nondebug libraries.

     For example, if your app invokes native methods in a library named
     mynm.dll (on Windows) or mynm.so (on Solaris), make a copy in the same
     directory and name it mynm_g.dll or mynm_g.so.

  9. (Sect. 4) An anonymous class can't seem to access a private outer
     method. Why is that?

     [*] It's a known bug in the JDK 1.1.4. The code is:

	 public class MyDialog {

	         void Setup() {
	         addWindowListener( new WindowAdapter() {
	               public void windowClosing(WindowEvent e) {
	                      myCloseWindow(); }
	               }
	               );     // anon inner class
	         }

	     private void myCloseWindow() {   // private outer method
	         dispose();
	     }
	 }

     This code sends javac into an infinite loop. The workaround is to make
     the private method non-private, or to make the inner class a named
     class. Sun put a workaround in the compiler to silently set the field
     to package access.

 10. (Sect. 4) What are the major Java releases and their contents?

     [*] There have been three Java releases from Sun so far, plus a number
     of bugfix (dot-dot) releases. The releases are:
	o JDK 1.0.2
	  This was the release FCS in May 1996. It had some security fixes
	  over JDK 1.0.
	o JDK 1.1
	  This release (Feb 1997) introduced a new event model in the window
	  system. It also made JDBC support and beans support a standard
	  feature. It changed and standardized the native code interface to
	  JNI. It also introduced inner classes.
	o JDK 1.2
	  This release (Dec 1998) made the Swing library a standard feature.
	  Swing is a set of rich platform-independent graphical components.
	  It also introduced the Collections library, and Java 2D.

 11. (Sect. 4) What is the difference between jre and java?

     [*] They are functionally equivalent, with minor differences in the
     handling of default classpath and options supported. To reduce
     confusion, the jre command was removed in JDK 1.2. Instead there is a
     "java" command in both bin and jre/bin.

     jre.exe is the java launcher that comes with the Java Runtime
     Environment. It ignores the CLASSPATH environment setting in favor of
     its own internally generated default and whatever is supplied on the
     cmd line using -cp or -classpath. It's intended to be a bit simpler for
     those who are only ever running Java programs, not developing them.

     java.exe is the java launcher that comes with the JDK. It uses the
     CLASSPATH environment setting as a starting point and then tacks on its
     own internally generated entries.

     They both serve the same purpose and that's to start a Java VM, have it
     run a Java application, then terminate. The source for jre.exe is
     provided in the JDK. The source to java.exe is provided only in the JDK
     Source distribution.

 12. (Sect. 4) What IDEs (Integrated Development Environments) are there?

     [*] Some popular IDEs include: (... if you have info on the platforms
     that each of these support, send it in, and I'll add it to the FAQ).
      Apptivity (Progress)   http://www.apptivity.com
      Blue J (free)          http://www.sd.monash.edu.au/bluej
      Bluette (free)         http://blue.donga.ac.kr/bluette/index.html
      Chicory (free)         http://www.chicory.com
      CodeWarrior
      Professional           http://www.metrowerks.com
      Freebuilder            http://www.freebuilder.org
      GRASP (free)           http://www.eng.auburn.edu/grasp
      Grinder                http://www.tpex.com
      Java WorkShop (Sun)    http://www.sun.com/workshop/java
      Javelin, Visual Object
      Development for Java   http://www.stepahead.com.au
      JBuilder (Inprise)     http://www.inprise.com/jbuilder
      JDE for emacs          http://sunsite.auc.dk/jde/
      Kawa (Webcetera)       http://www.tek-tools.com/kawa
      Metamata               http://www.metamata.com
      NetBeans (Swing-based) http://www.netbeans.com
      PARTS alpha
      (ObjectShare)          http://www.objectshare.com
      PowerJ (Sybase)        http://www.sybase.com/products/powerj
      SilverStream           http://www.silverstream.com
      Simplicity for Java    http://www.penumbrasoftware.com
      SuperCede (Asymetrix)  http://www.supercede.com
      teikade (PFU Ltd)      http://www.pfu.co.jp/teikade
      Together/J (Object Intl
      Inc.)                  http://www.oi.com
      Visaj (Imperial SW
      Tech)                  http://www.imperial-software-tech.co.uk
      VisualAge (IBM)        http://www.software.ibm.com/ad/vajava
      Visual Cafe (Symantec) http://cafe.symantec.com

      Visual J++ (Microsoft) http://msdn.microsoft.com/visualj/default.asp
	                     (not recommended)
      Xelfi 0.94             http://www.xelfi.com

 13. (Sect. 4) Why is Visual J++ not recommended?

     Because Microsoft's strategic objective is "Kill cross-platform Java"

     [*] It is not in Microsoft's financial interest to allow users to
     easily move software to different platforms. Microsoft is the only
     company in the computer industry that is actively trying to undermine
     Java. This is not speculation -- the Department of Justice's lawsuit
     quoted a Microsoft memo describing the strategic objective to "kill
     cross-platform Java by grow[ing] the polluted Java market". See
     http://www.usdoj.gov/atr/cases/f1700/1762.htm
     VJ++ can be used in a compatible way, but the tool encourages use of
     Windows lock-ins. The J++ compiler introduced new keywords and other
     deliberate incompatibilities.

     Microsoft is being sued because of unauthorized changes it made in
     Java. A federal judge issued a preliminary injunction against Microsoft
     in March 1998, prohibiting them from labelling their incompatible J++
     product as Java. Another injunction was issued against Microsoft in Nov
     1998, requiring them to remove some deliberate incompatibilities with
     standard Java. (Recall that Microsoft did not create Java, but
     contracted with Sun to distribute it).

     Microsoft is in a real jam over Java; it contracted with Sun to
     distribute standard Java, and then made many changes to its product
     to make it deliberately non-portable. Sun sued Microsoft to enforce the
     contract, and the preliminary legal decisions have been in Sun's favor.
     Some analysts speculate that Microsoft will leave its customers in the
     lurch and cancel VJ++. See
     http://cnn.com/TECH/computing/9903/23/javajam.idg/index.html

     Speak to your management chain - how comfortable do they feel using a
     Microsoft product that is embroiled in a legal dispute, that introduces
     deliberate incompatibilities, and whose stated goal is to lock you in
     to one platform? It is a safer choice to get standard Java from any
     other source than Microsoft. You can use these facts to move your
     company to standard Java.

     As a Java programmer please join the Java Lobby, an independent
     organization dedicated to representing independent non-vendor interests
     in Java. It's free, and you can sign up by visiting
     http://www.javalobby.org for details. Other ways to encourage portable
     java:
	o Use development environments from other vendors, or convert
	  Microsoft Visual J++ to use Sun's JDK, following the instructions
	  at http://www.orbiter.demon.co.uk/
	o Use Netscape Communicator (not Internet Explorer)
	o If required to use Internet Explorer, use the Java Plug-In to get
	  a standard Java system inside it.
	o Use a standard JVM from GNU, Kaffe, any of the IDE vendors, or Sun
	  (but not Microsoft's J++ SDK)

	o Free standard Java compilers and the Java Plug-In can be
	  downloaded from http://java.sun.com.
	o Free standard Java Virtual Machines can be downloaded from
	  http://www.kaffe.org, http://www.oryxsoft.com/projects/gvm, and
	  http://www.redhat.com/linux-info/jolt
	o Free Java AWT software can be downloaded from
	  http://www.biss-net.com/biss-awt.html and the files are all at
	  ftp.java-linux.org (the linux site) too.
	o Free Java software can be downloaded from
	  http://www.gnu.org/software/java/java.html

     Just for the record, the May 1998 federal case against Microsoft has
     nothing to do with innovation or product design, as Microsoft
     frequently insists. Microsoft is actually charged with
	o taking anti-competitive action to exclude competition in browsers,
	  in order to protect its monopoly in desktop operating systems.
	o using its monopoly to impose restrictive agreements that require
	  PC manufacturers to accept the Microsoft browser with Windows, and
	  that hinder the promotion of competing browsers.
     Many people think that contracts between "A" and "B",
     restricting/discouraging "B" from distributing "C's" products are
     sleazy. ["A" is Microsoft, "B" is AOL, many ISPs, computer vendors,
     etc. "C" is Netscape"]. Such contracts are in restraint of competition
     and illegal when used by a monopoly. This is why Microsoft is facing
     mounting legal problems in the United States, Italy, Brazil, and the
     European Union.

 14. (Sect. 4) What language is the Java compiler and JVM written in?

     [*] Sun's javac Java compiler is written in Java.
     Sun's java JVM interpreter is written in Java with some C, C++ for
     platform-specific and low level routines.
     Sun's Java Web Server is written in Java.

     Other companies have chosen other approaches. IBM's Jikes compiler
     (which is praised for its speed) is written in C++, but of course each
     version only runs on one platform. Jikes versions have been prepared
     for IBM AIX, Linux Intel (glibc), Win95/NT and Solaris Sparc at
     http://www.alphaworks.ibm.com/formula/jikes.

 15. (Sect. 4) How do I turn off the JIT in the JDK?

     [*] In JDK 1.1.x you use the commandline option "-Dnojit".
     In JDK 1.2/2 you use "-Djava.compiler=none"

     One reason for turning off the JIT is to get more information about any
     exception that is thrown in your code.

	               -------------------------------

5. Compiler Messages

     Most of the "questions" in this section are diagnostic messages from
     the compiler. Each answer explains what the message means, and how to
     avoid it.

  1. (Sect. 5) Why did I get an OutOfMemory error when porting working code
     from JDK 1.0.2 to 1.1?

     [*] The preset memory limit has changed. It went down to 16MB so as not
     to penalize low memory machines. You can adjust it with

	  java -mx128m Frotz        # jdk 1.1
	  java -Xmx128m Frotz       # jdk 1.2


     to get a 128MB extent.

     Also see the Runtime methods freeMemory() and totalMemory().

  2. (Sect. 5) Why do I get a "Statement not reached" error from javac for
     no apparent reason?

     [*] JDK 1.0 has a limit of 63 words of storage for local variables in
     any method. longs and doubles require two words of storage, and all
     other primitive types and all reference types require one word. If you
     assign values to more than 63 words of local variables, you will get a
     "Statement not reached" error on the statement after you assign to the
     variable that contains the 64th word. In JDK 1.1, the low limit was
     removed.

  3. (Sect. 5) class MyOrdinaryClass must be declared abstract.
     It does not define void actionPerformed(java.awt.event.ActionEvent)

     [*] This is one of those error messages where the compiler tries to
     guess what you meant, and gives you a message based on a wrong guess!
     So the message is confusing.

     Your MyOrdinaryClass class implements ActionListener, which means you
     must include a definition of the methods from the ActionListener
     interface.

     But you did not. You either left a method out, or (more likely) you
     misspelled its name. Perhaps you wrote "ActionListener" instead of
     "actionListener".

     So the compiler did not find the method to fulfill the interface. Since
     there was a method promised but not supplied, the compiler thinks you
     were aiming at an abstract class, and it prints an error message
     accordingly.

  4. (Sect. 5) Variable may not have been initialized.

	 URL test;
	 try {
	  test = new URL("http://osprey.avs.dec.com");
	 } catch (MalformedURLException e) {
	  System.out.println("bad URL:" + e.getMessage());
	 }
	 System.out.println("this is url " + test);


     [*] The compiler will warn you if you use a variable before it is
     certain to have been initialized (not just with the default value)
     since this means you probably forgot to set it.

     In the case of exceptions, you have to consider that the flow of
     control may terminate abruptly, with no operations completed. In the
     example above, if an exception is raised in the try clause, variable
     test will not be assigned a value, yet you are using it after the catch
     clause. One solution would be to declare test with an explicit initial
     value of null, but this works only because toString() works on a null
     reference. (toString() is invoked implicitly by operator + with String
     operand.)

     Always initialize to a value that will work notwithstanding exceptions
     being thrown.

  5. (Sect. 5) No constructor {superclass}()
     I extended the class called Frotz, and the compiler is giving me an
     error message "No constructor Frotz()" in the child class. Why?

     [*] When you define a constructor for a class, the compiler inserts a
     call to the superclass' parameterless constructor unless you explicitly
     call the superclass' constructor at the start of your constructor. If
     the superclass doesn't *have* a parameterless constructor, the compiler
     emits a message to that effect. The solution is usually to call the
     superclass' constructor at the start of your constructor.

  6. (Sect. 5) No constructor matching MyCheckbox(myApplet)

	 MyApplet.java:11: No constructor matching MyCheckbox(myApplet)
	 found in class MyCheckbox.

	 bp1 = new MyCheckbox(this);
	 ^

     [*] If a compiler isn't finding a constructor you thought you created,
     check whether you gave a return value to the method (remember,
     constructors have no return value). E.g.,

	 public void MyCheckbox( Container parent )


     If you did, the compiler will think it is an ordinary method, not a
     constructor. This is a common mistake and hard to spot.

  7. (Sect. 5) Type expected {public method variable}

	 public static void main(String[] args) {
	 ^
	 Statement expected.
	 public static final float Conversion_Factor = 39.37;
	 ^
	 Type expected.

     [*] Argument and variable declarations inside methods are never public
     or static because they are local to a method. (Before JDK 1.1 they
     couldn't be final either, but there was no good reason for that
     restriction and it was dropped.) If you have public or static
     variables, move them outside the method. They are usually put at the
     beginning of the class.

  8. (Sect. 5) Can't access protected method clone in class java.lang.Object

	 T.java:96: Can't access protected method clone in
	 class java.lang.Object. OtherT is not a subclass of
	 the current class.

     [*] Object.clone() is protected because subclasses might want to
     restrict access to cloning, and if Object.clone() were declared public,
     subclasses could never make it more restrictive. The subclass can make
     access to the clone() operation less restrictive.
     This means that a method can clone its own objects, but a method cannot
     clone objects of another class, unless you do something like:

	 class SomeObject implements Cloneable {
	     public Object clone()
	         throws CloneNotSupportedException {
	         return super.clone();
	     }
	 }


     i.e., override clone() to make it public, and call the superclass
     clone().

	 class Foo {
	  Bar bar;
	  Foo (Bar b) {
	      try {bar = (Bar) b.clone();}
	      catch (Exception e) {}
	  }
	 ...
	 class Bar implements Cloneable {
	  public Object clone()
	      throws java.lang.CloneNotSupportedException {
	      return super.clone();
	  }
	 }


     Another refinement is to note that Object.clone() only throws a
     CloneNotSupportedException when the object doesn't implement Cloneable.
     Since you control what your classes do and don't implement, you can
     ensure that Cloneable classes implement the interface, and you don't
     need to make the overridden clone() throw the exception.

	 public class X implements Cloneable {
	     public Object clone() { // no throws
	         try {
	                   // in case members need cloning
	             X c = (X)super.clone();
	             return c;
	            } catch (CloneNotSupportedException e) {
	            // should not happen, because of Cloneable
	                throw new InternalError();
	            }
	        }
	 }


  9. (Sect. 5) Deprecated methods
     What does "deprecated" mean? I got this in a compiler error message.

     [*] "Deprecated" means you are using an older API, that Sun has
     replaced with a newer one (usually to follow more consistent naming
     conventions). Deprecated methods are not recommended for use. They are
     supported in the short term, but your code should be updated with the
     new. To update your code, compile your old code using javac's
     "-deprecation" option to list deprecated methods, then find the
     replacement methods in the current HTML API documentation for the old
     deprecated methods.
     As an example of a deprecated API, Component.size() was replaced by
     Component.getSize().

     See also
     http://java.sun.com/products/jdk/1.1/docs/guide/
     misc/deprecation/index.html, "1.1 Deprecated Methods"
     and
     http://java.sun.com/products/jdk/1.1/docs/guide/
     awt/DeprecatedMethods.html, "Deprecated methods in the 1.1 AWT"

 10. (Sect. 5) double y = sin(90);
     What's wrong? That code provokes compiler messages.

     [*] You need to write it this way:

	 double cvtDegToRad = Math.PI/180;
	 double x = 90*cvtDegToRad;
	 double y = Math.sin(x);


     sin is a static method of the Math class that takes radians. You need
     to use the "Math" classname, e.g. Math.sin instead of plain sin,
     because you have to say what class or object these methods belong to.

     A very common mistake is to assume that importing a class means that
     you don't have to qualify the names of its members. When you call a
     method you have to state the name of the class or object it belongs to,
     regardless of any imports you have done. (Except inside the class
     itself, obviously).

     The trig functions are static methods of the Math class, so you give
     the name of the class in invoking them. Further, the Math class works
     in radians, not degrees. 360 degrees = 2 pi radians, so use a
     conversion factor as shown if you are working with degrees.

 11. (Sect. 5) Can't make static reference to method...

     [*] Your code probably looks something like this:

	 class myclass {
	     public static void main(String args[]) {
	       myMethod();
	     }
	     public void myMethod() { //some code
	     }
	 }


     Static (class) methods can only call without qualification other static
     methods, so you either have to qualify the call in (static) main() to
     (nonstatic) myMethod() with an object of type myclass, or you have to
     make myMethod() static.

     People often forget that even though main is "in" myclass, there is no
     implicit object when you are in main() because it is static. This
     happens especially when writing code to run an applet as an
     application, where you want to call init() and start() from main.

	 public static void main(String[] args) {
	     Applet ma = new myApplet(); // have to create object
	     ma.init();  // use to qualify access to non-static methods
	     ma.start();
	 }


 12. (Sect. 5) Incompatible type for =. Explicit cast needed...

	 byte b = 0;
	 Incompatible type for =.
	 Explicit cast needed to convert int to byte.
	 b = b + 100;    // compiler error message
	 b += 100;       // works OK


     [*] Arithmetic expressions are promoted to the type of the longest,
     floatiest operand in them, or at least to int. The first statement
     involves the assignment of an expression. The expression is promoted to
     32 bits, and must be cast back down to 8 bits, like this: b = (byte)
     (b+100); The second is an operator assignment, and the cast back to
     byte takes place automatically. The Java Language Specification says
     that a compound assignment expression of the form E1 op= E2 is
     equivalent to E1 = (typecast)((E1) op (E2)), where "typecast" is the
     type of E1, except that E1 is evaluated only once. (See JLS 15.25.2
     Compound Assignment Operators) The compile-time narrowing of constants
     means that code such as:

	 byte theAnswer = 42;


     is allowed, with no cast necessary. (See JLS 5.2 Assignment Conversion)

     Other sites:
     JLS 5.2 Assignment Conversion
     JLS 15.25.2 Compound Assignment Operators

 13. (Sect. 5) Class {package}.{class} not found in type declaration.
     I am trying to compile file "{class2}.java" in a package, and I get
     this compiler error. {class2}.java refers to {package}.{class}, but the
     file {class}.java and {class2}.java are in the same {package}
     directory, which is the current directory and which is in the CLASSPATH
     variable. Both files have "package {package};" at the top of the file.
     What's the problem?

     [*] When the source refers to classes in packages, the CLASSPATH has to
     point to the root of the package/directory hierarchy for a reference to
     resolve correctly. This is true even for source files in the same
     package (and directory). I.e., assuming {class} and {class2} are both
     in {package}, {class} can't make a reference to {class2} unless the
     CLASSPATH is set so javac can find {package}/{class2}.java. It should
     make no difference what directory you are in when you invoke javac,
     unless you are relying on "." in the CLASSPATH to point to the package
     root or are specifying the source file with a relative path (e.g.,
     {package}/{class}.java).

     Some examples, assuming
	o - Foo.java and Bar.java are in /java/source/pack/
	o - Both have "package pack;" as the first statement
	o - Foo.java includes "Bar b = new Bar();"

	 # solaris ksh
	 $ alias jc=/java/jdk11/bin/javac
	 $ CLASSPATH=/java/source/
	 $ jc /java/source/pack/*.java  # works fine
	 $ cd /java/source/pack
	 $ CLASSPATH=.
	 $ jc *.java         # fails - Foo.java can't find class Bar
	 $ cd ..             # now . is package root, /java/source/
	 $ jc pack/*.java    # works


 14. (Sect. 5) public class "Foo" must be defined in "Foo.java"
     I get this message even though it is in Foo.java. What gives?

     [*] Javac verifies that a public class is defined in a file of the same
     name (e.g., that public class Foo is defined in Foo.java). Two things
     you can check:

     First, make sure the case matches exactly. public class Foo cannot be
     in foo.java; it has to be in Foo.java.

     Second, are you using MKS on win32? Javac on win32 assumes you are
     using the DOS path separator (\) even though MKS accepts the Unix path
     separator (/). When javac tries to parse a your Unix-style path, it
     won't produce the correct filename, the match will fail, and it will
     emit an error. You have to use the DOS path separator (\), which must
     be escaped in MKS - e.g., "javac H:\\source\\package\\Foo.java".
     Alternatively, you can traverse to each source directory and avoid
     pathnames altogether.

	               -------------------------------

6. Java Language Issues

     How-to

  1. (Sect 6.) How do I compare two Strings?

     if (s1 == s2)

     is giving me funny results.

     [*] The comparison using "==" on objects, such as Strings, is asking,
     "Do these two objects have the same reference?" Do they have the same
     address, and hence are the same object? What you really want to do is
     ask, "Do these two Strings have the same *contents*?"
     Compare String contents with any of the following:

	 if (s1.equals(s2) )
	 if (s1.equalsIgnoreCase(s2) )
	 if (s1.startsWith(s2) )
	 if (s1.endsWith(s2) )
	 if (s1.regionMatches(s1_offset, s2, s2_offset, length) )
	 if (s1.compareTo(s2) < 0)


     (There are other ways, too.)
     Note that you can do this with literals:

     if ("apple".equals(s2) ) ...


     If you compare these the other way round, like this:

     if ( s2.equals("apple") ) ...


     and s2 is null, you will get a null pointer exception.

  2. (Sect. 6) How do you get the code value of a char?
     I would like to transform a char into the corresponding int value, that
     represents the code value of the char. How?

     [*] Like this.

	 char c = 'A';
	 int i = c;


     Going the other way is just

	 c = (char) i;


     This question crops up so frequently because the BASIC language uses
     functions to map characters into ints, ASC( 'A' ) => 65 causing BASIC
     programmers to seek the corresponding Java functions. The same is true
     for Pascal, Ada, and other languages.

  3. (Sect. 6) Why does b >>>= 1 give me the same result as b >>= 1?

     [*] ">>" is a "signed" or "arithmetic" shift, namely, it replicates the
     sign bit on the left as it shifts.
     The ">>>" operator is an "unsigned" or "logical" shift; it does a shift
     right and zero fill. However, ">>>" looks like it does a signed shift
     with negative bytes and shorts, where int promotion alters the sign.

     This occurs when you have a non-canonical type, byte, or short, with a
     negative value, e.g.

	 byte b = -15; // 0xf1
	 b = (byte) b >>> 4; // why isn't b 0x0f ?


     The initial expectation is that an unsigned shift right of 0xf1 would
     successively be (in binary)

	 0111_1000 then
	 0011_1100 then
	 0001_1110 then
	 0000_1111


     But that doesn't happen. The rules of arithmetic in Java say that all
     operands are converted at least to int before the operation (and
     possibly to a more capacious type). That means our byte is promoted to
     an int, so instead of shifting 0xf1, we are shifting 0xfffffff1. If you
     shift right unsigned 4 places, you get 0x0fffffff. When you cast that
     to a byte it becomes 0xff, or -1.

     The bottom line is that the final result is the same as if you had
     performed the signed shift because the unsigned shift applied to the
     intermediate int, not to the original byte. This anomaly means that
     ">>>" is useless for negative bytes and shorts. It is probably safer
     and clearer not to use it at all, but to mask and shift instead:

	 // not recommended
	 byte b = -15;
	 b = (byte) (b>>>4);
	 System.out.println("b= "+Integer.toHexString(b) );
	 // recommended
	 b = -15;
	 b = (byte) ( (b & 0xFF) >> 4 );
	 System.out.println("b= "+Integer.toHexString(b) );


  4. (Sect. 6) Why does the  happen in floating point?

     [*] There are several unexpected things that seem to bite programmers
     with floating point. This is almost always a result of the programmer
     not being fully conversant with floating point arithmetic in general,
     rather than a problem relating to Java.

     The question of floating point accuracy comes up with Java more than
     with C++ (for example) because of Java's decision in the println()
     method to print enough digits to distinguish the number from the
     next-closest number, rather than rounding it to 6 significant digits by
     default as the C/C++ libraries do. [ISO C, Sect 7.9.6.1, line 21 of
     "the double argument"]

     If you seem to be having problems with floating point, the problem
     probably stems from the fact that floating-point arithmetic is
     inherently imprecise. You can expect up to 7 digits of precision with
     floats and 16 digits with doubles. However, that does not mean that a
     number that can be exactly represented in 7 digits decimal or can be
     exactly represented as a binary floating point number. On the contrary,
     that is usually not the case.

     Additionally, when Java converts floating point numbers to a String, as
     is done when they are output, enough digits are printed so the number
     can be read back in with no loss of precision. For this reason, you may
     see more "inaccuracies" in floating point output than you are used to.
     You are actually getting more accuracy than on systems (like C,C++)
     that suppress the less significant digits.

     For more information and detailed specifications on how Java deals with
     floating point, see the URLs listed below.

     Other sites:
     What Every Computer Scientist Should Know About Floating Point.
     http://java.sun.com/products/jdk/1.1/compatibility.html#incompatibilities

     JLS 4.2.4 Floating-Point Operations
     JLS 3.10.2 Floating-Point Literals
     JLS 5.2.3 Narrowing Primitive Conversions
     http://gams.nist.gov/javanumerics/jgfnwg-01.html

     If you want the rounded floating point output that most languages have,
     use the new java.text package of Java 1.1 to limit the number of digits
     that are output. If you need more precision than about 16 digits, use
     the BigInteger and BigDecimal classes of Java 1.1.

     Understanding the Java Language

  5. (Sect. 6) How can I program linked lists if Java doesn't have pointers?

     [*] Of all the misconceptions about Java, this is the most egregious.
     Far from not having pointers, in Java, object-oriented programming is
     conducted exclusively with pointers. In other words, objects are only
     ever accessed through pointers, never directly. The pointers are termed
     "references" and they are automatically dereferenced for you.

     Java does not have pointer arithmetic or untyped casting. By removing
     the ability for programmers to create and modify pointers in arbitrary
     ways, Java makes memory management more reliable, while still allowing
     dynamic data structures. Also note that Java has NullPointerException,
     not NullReferenceException.

     A linked list class in Java might start like this:

	 public class LinkedList {
	     public LinkedList head;
	     public LinkedList next;
	     public Object data;
	     public LinkedList advanceToNext(LinkedList current) { ...
	 }


     Another choice for a linked list structure is to use the built-in class
     java.util.Vector which accepts and stores arbitrary amounts of Object
     data (as a linked list does), and retrieves it by index number on
     demand (as an array does). It grows automatically as needed to
     accommodate more elements. Insertion at the front of a Vector is a slow
     operation compared with insertion in a linked list, but retrieval is
     fast. Which is more important in the application you have?

  6. (Sect. 6) Are parameters in Java passed by value or by reference?

     [*] All parameters (values of primitive types and values that are
     references to objects) are passed by value. However this does not tell
     the whole story, since objects are always manipulated through reference
     variables in Java. Thus one can equally say that objects are passed by
     reference (and the reference variable is passed by value). This is a
     consequence of the fact that variables do not take on the values of
     "objects" but values of "references to objects" as described in the
     previous question on linked lists.

     Bottom line: The caller's copy of primitive type arguments (int, char,
     etc.) _do not_ change when the corresponding parameter is changed.
     However, the fields of the caller's object _do_ change when the called
     method changes the corresponding fields of the object (reference)
     passed as a parameter.

     Also in this FAQ:
     How can I program linked lists if Java doesn't have pointers?
     Other sites:
     JLS 8.4.1 Formal Parameters

  7. (Sect. 6) What are "class literals"?

     [*] A feature introduced in JDK 1.1. They are literals of type "Class"
     that hold a value representing any class. There are even values to
     represent "void" and an array, like this:

	 Class myCl1 = Character.class;
	 Class myCl2 = Void.class;
	 Class myCl3 = Object.class;
	 Class myCl4 = String[].class;
	 Class myCl5 = int[][].class;


     You might use it like this:

	 Class cl = thing.getClass();
	 if (cl.equals(myCl1))
	 System.out.println("It's a Character class");


     Note that a class literal

	     Component.class


     is the equivalent of

	     Class.forName("java.awt.Component")


     The second can throw an exception, but the first cannot. If you don't
     know the name of the class when you write the code, you cannot use the
     first form.

  8. (Sect. 6) What are the naming conventions in Java?

     [*] The naming conventions are straightforward:
       1. Package names are guaranteed uniqueness by using the Internet
	  domain name in reverse order: com.javasoft.jag - the "com" or
	  "edu" (etc.) part used to be in upper case, but now lower case is
	  the recommendation.
       2. Class and interface names are descriptive nouns, with the first
	  letter of each word capitalized: PolarCoords. Interfaces are often
	  (not always) called "something-able", e.g. "Runnable", "Sortable".
	  Caution: java.util.Observable is not an interface, though
	  java.util.Observer is. These two are poorly designed.
       3. Object and data (field) names are nouns/noun phrases, with the
	  first letter lowercase, and the first letter of subsequent words
	  capitalized: currentLimit
       4. Method names are verbs/verb phrases, with the first letter
	  lowercase, and the first letter of subsequent words capitalized:
	  calculateCurrentLimit
       5. Constant (final) names are in caps: UPPER_LIMIT
       6. Also in the FAQ:
	  Where can I find a Java style guide on naming conventions?
	  Other sites:
	  JLS 6.8 Naming Conventions

  9. (Sect. 6) Should I prefer importing {package}.{class} over {package}.*?

     Does it make a difference to the class file in any way, if I import a
     package versus use the full name, i.e.

	 import java.rmi.server.*;
	 ...
	 RemoteObject ro;

     versus:

	 java.rmi.server.RemoteObject ro;

     [*] No, it makes no difference to the class files or runtime speed.
     Import is just a shorthand for quoting the full name package and class
     name (as in the examples in the question). Importing a class does not
     cause the class to be loaded at run time. There is no runtime penalty
     for using the * form of import. The class file will contain the name of
     the packages it uses, and the loader will look for those classes as
     needed at runtime.

     At compile time, the different forms of import may or may not make a
     difference to compile time. Such a difference is likely to be
     negligible, and should not be a factor in which form of import you use.

     However, there are style advantages. Some say that stating which
     classes you are importing can help program readability. In a program
     with many * import statements, it may take a programmer time to find
     which package an obscure class is imported from. If you explicitly list
     each class you import at the top of the program, you document which
     package each class you use comes from. These people suggest that you
     use

     import java.rmi.server.RemoteObject;


     in preference to:

     import java.rmi.server.*;


     Other people say that it is clearer still to use the full package and
     class name, at the point where you use classes in other packages.
     These people suggest that you use:

     java.rmi.server.RemoteObject ro;


     But that gets a little lengthy when you instantiate:

	     java.rmi.server.RemoteObject ro
	               = new java.rmi.server.RemoteObject();


     You always have the option of stating the full package and class name,
     whether you use import or not.

     Another good reason not to use the * form is when you are importing two
     packages that have classes of the same name and you want to use only
     one of those classes. E.g.

	 import com.sun.*;
	 import com.ms.*;


     where there is a class called Modem in both those packages. If you use
     the * form of import, you import both of the Modem classes and then
     must fully qualify the class each time you use it, to say which of the
     two you mean. In Java 1.2, the class java.util.List was introduced.
     That had the same unqualified name as java.awt.List. If your code had
     "import java.awt.*; import java.util.*;" it would no longer compile.
     You'd get a message about ambiguous classname. If you import all of a
     package indiscriminately you might get bitten when the package API
     changes.

     In Java 1.0, if you import a class that has the same name as a class
     defined in that source file, you will get an error that the class names
     clash. In Java 1.1, the local class will be used when the package name
     is not given; to use the imported class, you have to use the full
     package name.

     The best advice is to write the program so that it is as readable as
     possible. Where you have a group of well-known classes, as in java.awt,
     there is no reason not to use "import java.awt.*;"

 10. (Sect. 6) How can I use Math.cos() etc. without the prefix "Math."?
     Is there some declaration that I can use to make "acos", "cos", "sin",
     etc. (from java.lang.Math) recognizable in my own class, so I don't
     have to prefix "Math." to them?

     [*] No. There is no good alternative. There are several bad
     alternatives:
       1. Using "import" doesn't work.
	  The import stament only imports packages, subpackages, and
	  classes, not class members. This doesn't work:

	          import java.lang.Math.*;


       2. Minimizing class name usage is unclear and bad style.
	  - You could wrap the functions in your own class.

	      double sin(double x) {
	          return Math.sin(x);
	      } // etc. for each function


	  But you'd have to use your class name everywhere but inside your
	  class, so it doesn't help.
	  - You can make a null reference to the Math class and use it to
	  refer to the static methods. Declare

	      java.lang.Math M = null;
	      angle = M.cos(i);


	  Besides not being clear, this invites abuse and errors.

	  - You could inherit the names
	  If java.lang.Math were not final and your class did not extend
	  another class, you could have your class extend Math, to bring the
	  namespace in. However, it is poor OOP style to use inheritance to
	  obtain a name abbreviation rather than to express a type
	  hierarchy.

 11. (Sect. 6) Why is there a standard JNI?

     [*] JNI is the Java Native Interface. It defines the way that a Java
     program can call C programs. The industry has agreed on, and Sun has
     codified, JNI as the standard. Microsoft shuns the standard and uses a
     protocol of its own called Raw Native Interface, RNI.

     You might think that once a Java program uses JNI, portability is lost,
     and hence it doesn't matter if vendors diverge from the JNI standard.
     Not so. Code that accesses a native library using JNI can run on any VM
     that supports JNI, so it's portable across VMs on the same platform.
     Further, you can port a native library to all platforms Java supports
     (indeed, this is how Sun implements the Java Platform), so JNI
     _enables_ cross-platform development where it's necessary to use
     platform-specific idioms for certain functionality.

     Conversely, code that uses RNI can only run on Microsoft's VMs on the
     win32 platform. Microsoft's RNI has the effect of limiting RNI programs
     to the Microsoft VM. Further, Microsoft's failure to support JNI locks
     out JNI-based functionality on Windows. Microsoft's non-standard RNI is
     the reason that programs using the Microsoft JVM cannot use the
     standard Java jdbc-odbc library. That library has a piece written in C.
     It works for all JVMs except Microsoft's.

     The standard JNI thus has two purposes:
       1. Source code compatibility between different platforms.
       2. Binary code compatibility between different JVMs on the same
	  platform.
     Microsoft's use of RNI locks in programmers who use it, and Microsoft's
     failure to support JNI locks out programmers who don't use RNI. Users
     can't run standard JNI applications on Microsoft VMs, or RNI
     applications on non-Microsoft VM's. As a result, since most users will
     support only one VM, they'll be locked in to complementary software -
     in the case of Microsoft, a proprietary standard. A standard JNI means
     that you can use any standard JVM to run your code on this platform.

 12. (Sect. 6) How do I find out more about JNI? How do I find out more
     about Java Anything?

     [*] Taking the questions one at a time. Use of JNI detracts from
     program portability. So you would only do it when you need some
     critical single-platform effect. The documentation on JNI is at:
     http://java.sun.com/docs/books/tutorial/native1.1/index.html

     If your interest extends to reading a book on JNI, a good one is
     "Essential JNI Java Native Interface" by Rob Gordon; ISBN
     0-13-679895-0. See
     http://www.amazon.com/exec/obidos/ASIN/0136798950/afuinc

     In general, if you want to find out about topic "X" in Java, your first
     stop should be to search the http://java.sun.com website for "X". For
     example if you want to know about Internationalization in Java, a
     search at the site quickly takes you to
     http://java.sun.com/products/jdk/1.1/docs/guide/intl/intlTOC.doc.html.

 13. (Sect. 6) How do I get unsigned ints in Java?

     [*] Java doesn't have unsigned ints. The reason is that this is a
     poorly designed area of C. The rules for what type you end up with when
     you mix signed and unsigned in expressions are complicated, and they
     changed between K&R and ANSI C (you might have heard this under the
     name "unsigned preserving vs. value preserving"). Worse, they depended
     on the underlying hardware, so they varied from platform to platform,
     causing bugs in all kinds of unexpected places. The book "Expert C
     Programming" goes into this in more depth (page 25). So, to avoid
     bringing over the hidden complexities, Java does not bring over
     unsigned types from C.
     Use type char if you are OK with 16-bit unsigned quantities. Otherwise,
     go to the next larger type and use masking. Specifically, to convert an
     int to its unsigned representation, use:

	     ((long)i) & 0x00000000FFFFFFFFL


     This promotes the signed int to long (with sign extension) then chops
     off the sign-extension, leaving it as a positive 32-bit quantity held
     in a 64-bit type.
     Also worth noting is that if you're going to work with unsigned bytes,
     int is a more efficient larger type to use than short or char, since
     smaller values have to be promoted to int to do any arithmetic or
     testing on them.

 14. (Sect. 6) What happened to "private protected"?

     [*] It first appeared in JDK 1.0 FCS (it had not been in the betas).
     Then it was removed in JDK 1.0.1. It was an ugly hack syntax-wise, and
     it didn't fit consistently with the other access modifiers. It never
     worked properly: in the versions of the JDK before it was removed,
     calls to private protected methods were not dynamically bound, as they
     should have been. It added very little capability to the language. It's
     always a bad idea to reuse existing keywords with a different meaning.
     Using two of them together only compounds the sin.

     The official story is that it was a bug. That's not the full story.
     Private protected was put in because it was championed by a strong
     advocate. It was pulled out when he was overruled by popular
     acclamation.

     Inheritance

 15. What are the differences between an interface and an abstract class?

     [*] Some use a semantic distinction: an abstract superclass models the
     "is" relationship, while an interface models the "has" relationship.
     The rule would be, if it's a subtype, inherit; otherwise, implement.

     But, in the absence of real-world characteristics to distinguish the
     objects from their properties and parents, that becomes a circular
     argument. In this case, you have to look at the practical differences
     in Java (compared with C++).

     Most differences between interfaces and abstract classes stem from
     three characteristics:
       1. Both define method signatures that a derived class will have.
       2. An abstract class can also define a partial implementation.
       3. A class can implement many interfaces, but inherit from only one
	  class.

     In greater detail, these topics are:
       1. Method signatures Both interfaces and abstract classes permit one
	  to treat the derived-type class as the derived-from-type class.
	  Both define a set of available methods in a way that can be
	  enforced by the type-checking mechanism. This is typically used to
	  permit different (derived) types to behave in the same way (as
	  what they are derived from - i.e., they all support particular
	  methods). For example, all java.* types can be printed as Strings
	  because Object, the superclass of all java.* types, has a
	  toString() method. Similarly, all types that implement the
	  Observable interface can be passed an Observer to signal when an
	  event has occurred. This permits an algorithm or service to
	  operate on different (derived) types as if they were the same
	  (derived-from) type.
	  This mechanism supports not only polymorphism (one object treated
	  as another), but differentiation. In either case, the (derived)
	  types can implement the method in the way appropriate to that
	  type. However, you're not likely to override inherited
	  functionality, but you must implement interface methods, so if you
	  expect significant differentiation, then an interface might be
	  warranted.
	  Finally, this mechanism supports a weak variant of access control.
	  Only inherited methods are available to callers who only have a
	  reference to the superclass or interface type. It's weak because
	  they can attempt a narrowing cast if they know their target type.
	  Nonetheless, it reduces some complexity.
       2. Inheriting implementation Inheriting an implementation is useful
	  where the code should be shared. This happens where derived types
	  vary the functionality only a little bit, or where a complex set
	  of method interfaces can through mutual reference be implemented
	  with relatively few methods that can be implemented by derived
	  types. You can also reuse code by having your class use or keep an
	  object of another type that implements that code, but that doesn't
	  permit your callers to treat you in a particular way. To both
	  "get" functionality and to be treated "as" the superclass are the
	  essentials of the type/subtype relationship.
       3. Java's rule of single inheritance Java differs from C++ in
	  permitting only single inheritance. This makes for some difficult
	  choices, if you would like to share combinations of inherited
	  functionality and polymorphism from more than one source. However,
	  it does reinforce the notion of inheritance as a subtyping (is)
	  relationship, and implicitly that type relationships form a tree
	  rather than a network.

     Other differences to consider:
       1. Abstract class implementations may include fields
       2. Interfaces may include final data members
       3. It is slightly slower to call an implemented method via an
	  interface reference. There is an even smaller penalty for calling
	  a superclass method via a subclass reference (i.e., where the
	  subclass does not override the method). There is almost no penalty
	  for calling a subclass method via a superclass reference. (All are
	  compared to a direct method call, i.e., calling the derived class
	  method via a derived class reference).

 16. (Sect. 6) How do static methods interact with inheritance?

     [*] Static (per-class, rather than per-object) methods do not
     participate in overriding (choosing the right method at runtime based
     on the class of the object). Probably the best and simplest way to
     think about this (and to write your code) is to write every invocation
     of a static method using the fully qualified class name:

	 class A {
	 public static method1() {
	         A.method2();
	     }
	 public static method2() {
	     }
	 }

	 class B extends A {
	     public static method3() {
	         A.method1();
	     }
	     public static method2() {
	     }
	 }


     Now it is perfectly clear that the static method2() that is called is
     A.method2(), not B.method2(). A.method2() will be called regardless of
     whether you use the fully-qualified class name or not, but using "A."
     makes it obvious to all.

 17. (Sect. 6) Why is the String class final? I often want to override it.

     [*] Being final guarantees that instances of String are read-only. (The
     String class implements read-only objects, but if it were not final it
     would be possible to write a subclass of String which permitted
     instances to be changed.) Strings need to be read-only for security and
     efficiency.

     As for efficiency, Strings are very commonly used, even behind the
     scenes by the Java compiler. Efficiency gains in the String class yield
     big dividends. If no one can change a String, then you never have to
     worry about who else has a reference to your String. It's easier to
     optimize accesses to an object that is known to be unchanging.

     Security is a more compelling reason. Before String was changed to be
     final (while Java 1.0 was still in beta) there was a race condition
     which could be used to subvert security restrictions. It had to do with
     one thread changing a pathname to a file after another thread had
     checked that the access was permitted and was about to open it.

     There are other ways to solve these problems, but the designers
     preferred making String final, particularly since the StringBuffer
     class is available as an alternative.

 18. (Sect. 6) If I extend/subclass a class, are the constructors inherited?

     [*] "Constructor declarations are not members. They are never inherited
     and therefore are not subject to hiding or overriding." The default
     constructor is not inherited, but provided. (See JLS 8.6.7 Default
     Constructors)

     If you don't give your child class any constructors, a default no-arg
     constructor that invokes the superclass' constructor is provided for
     you. If the superclass doesn't have a no-arg constructor, you should
     create a constructor and call the appropriate superclass constructor.

     Also in the FAQ:
     Compiler message No constructor {superclass}()

     Other sites:
     JLS 8.6.7 Default Constructors

 19. (Sect. 6) How can I safely store particular types in general
     containers?
     I often want to store particular types of objects but don't want to
     subclass my basic storage classes to enforce the particular type; that
     would make for too many subclasses (e.g., IntegerLinkedList,
     StringLinkedList, etc.).

     [*] Generic programming in java (the rough equivalent of C++'s
     templates) works reasonably well since all java classes are subclasses
     of Object. There is, however one potential problem - there is always a
     possibility that a generic container may contain different classes of
     objects.

     This naturally leads to the question of how to do this in a type-safe
     way. If you've created a generic LinkedList class, how can you be type
     safe without having to create a multitude of subclasses
     (IntegerLinkedList, StringLinkedList, etc.)?

     One way to handle this would be to offer up an additional constructor
     in your generic class that takes a parameter of type "Class" and uses
     that parameter along with Class's "isInstance" method to guarantee that
     Objects added to the container are the expected type.

	 public class LinkedList {
	     Protected Class type = Object.class;

	     public LinkedList(Class type) { this.type = type; }

	     public void addElement(Object element) throws Exception
	     {
	     if(!type.isInstance( element ))
	         throw new Exception(
	              "Expected element of type (" + type    + ")" +
	              " got element of type ("     + element + ")"   );
	      ...
	      }
	  }


     Note that the comments in the source for isInstance() refer to a
     "specified Class parameter", suggesting that you are supposed to write
     something like:

	     public void addElement(Object element) throws Exception
	 {
	     Class c = element.getClass();
	     if(!type.isInstance(c))


     This works, but the documentation for isInstance is clear that the
     parameter should be an Object rather than a Class. Also, note that
     "Collections" are coming in JDK 1.2, and they provide a much safer and
     more extensible mechanism. More information about this is available at
     the Java Developer Connection at the Java website: http://java.sun.com/

     Method interfaces

 20. How do I send a variable number of arguments to a method?

     [*]
       1. (Easy) Use method overloading to support different parameters.
	  This makes things easy on the caller but can get out of hand if
	  you want to support a wide number and variety of parameter types.
	  You should ask yourself if your code design is well-organized if
	  you need to do this.
       2. (More complicated) Use arrays. It's even possible to declare
	  arrays inline as shown below:

	      foo("A param",
	          new Object[] {"param3", "param4", new Integer(5)} );
	   // ...

	   void foo(String param1, Object param2[]) {
	       System.out.println(param1);
	       for (int i = 0; i < param2.length; i++) {
	           System.out.println(param2[i].toString());
	       }
	   }


	  You can even pass arrays of arrays using this method. Of course,
	  inside the method you need to be able to decode what the arguments
	  are and how you use them.
       3. Alternatively you can invent a class that just contains all the
	  possible fields you might want to pass into a method (plus
	  booleans to say if each field is set or not), and make an object
	  of that class be a parameter to the method. You can return
	  multiple values from a method the same ways; either have the
	  method return an array or a wrapper object.

     However, remember the wise words of Professor Alan Perlis, "if your
     procedure has more than about half a dozen parameters, you probably
     forgot a few." Passing large numbers of arguments into a function
     suggests your function is badly organized.

 21. (Sect. 6) How can I return a different object in a method parameter?
     How can I pass an object to a method, and have the method change the
     reference so it points to a different object back in the calling code?

     [*] There are two ways. The obvious way is "just add another level of
     indirection". Wrap the object in another class, whose purpose is simply
     to be passed as a parameter, allowing the nested object reference to be
     modified.
     The second alternative is a clearer variant of this. Pass in a single
     element array. Since arrays are objects, this works.

	     void jfoo(Object ref[]){
	     ref[0] = new Object();
	 }
	 ...
	 Object kludge[] = new Object[1];
	 kludge[0]= myObj;
	 jfoo(kludge);
	 if (kludge[0] == myObj) ...
	 else ...


     Note that changing a global variable/object inside a method is an
     egregious programming practice; it usually violates basic OOP
     constructs.

 22. (Sect. 6) How do I get multiple return values back from a method?

     [*] You can just have the function return a Vector. This is
     particularly convenient when you're not sure how much you are going to
     be returning, based on what occurs in the method. A Vector is
     essentially a dynamically-growable array. Regular arrays can't grow
     after you declare them - you have to declare a bigger array and move
     the old stuff into it.

     Arrays

 23. (Sect. 6) How do I allocate a multidimensional array?

     [*] There are several ways. If you want a rectangular array, you can
     allocate the space for the array all at once. The following creates a
     4x5 array:

	 int arr[][] = new int[4][5];


     If you want each row to have a different number of columns, you can use
     the fact that a two-dimensional array is actually an array of arrays.
     The following code allocates a triangular array:

	 int arr[][] = new int[4][];    // allocate the four row arrays
	 for (int i = 0; i < 4; i++) // initialize each of the four rows
	 arr[i] = new int[i + 1];       // row i has i + 1 columns


     Note that if you allocate an array of any kind of object (as opposed to
     primitive type), all the references will be null by default. These null
     references can result in NullPointerExceptions if you try to
     dereference them.
     In other words, after doing:

	 int arr[] = new int[4];


     you can say

	     if (arr[2] == 0)


     But after doing

	     Integer Iarr[] = new Integer[4];


     you must fill in the object reference before using it. E.g.,

	     Iarr[2] = myInt;


     or

	     arr[2] = new Int(27);


     before you can say

	     if (Iarr[2].equals(myInt))


 24. (Sect. 6) How do I copy an array?

     [*] If the array only contains primitive types or if you want to copy
     only the object references, not duplicate the objects, then use the
     method

	 java.lang.System.arraycopy(Object src, int src_position,
	     Object dst, int dst_position, int length);


     Otherwise, if you want to duplicate the objects, you have to initialize
     your new array and write a loop that duplicates each object in the old
     array into the new.

     Note that the documentation for arraycopy() says that if src and dst
     refer to the same object, then arraycopy behaves as if the source array
     elements are copied into a temporary array (i.e., they are preserved).
     Some interpret this as meaning a temporary array will be so allocated,
     but that's not Sun's implementation.

     Other sites:
     JLS 20.18.16 {java.lang.System.arraycopy()}

 25. (Sect. 6) How do I clear an array?

     [*] There is no method to clear an array to 0.0, 0, null, false,
     '\u0000' etc. When you allocate an array, the elements are set to their
     default values, but that doesn't help when you want to reuse an array.

     If you want to set the same array to the same set of values many times,
     create a template array. Fill it with the reset value, then use
     System.arraycopy() to copy it into the work array each time you need to
     set the work array.

 26. (Sect. 6) What is a fast way to set all elements of an array?
     I don't want to use a template array. I would like to set all array
     elements to a given value without duplicating the (possibly large)
     array.

     [*] Using a loop that does it one by one is probably 20 to 40 times
     slower than good old memset() in C.

     A fast way on many VM's is to set the first byte of the array, then use
     System.arraycopy() repeatedly to fill the next byte, the next two
     bytes, the next four bytes, the next eight bytes, etc., and when you
     get past halfway, fill in the rest.

	 public static void bytefill(byte[] array, byte value) {
	 int len = array.length;
	 if (len > 0)
	 array[0] = value;
	 for (int i = 1; i < len; i += i)
	     System.arraycopy( array, 0, array, i,
	         ((len - i) < i) ? (len - i) : i);
	 }


     This is faster on Sun's VM than a simple loop, and probably even faster
     under JITs because it only performs at most log2(array.length) bounds
     checks. This is a clever code idiom applying the binary chop algorithm
     to arrays even when their size is not a power of 2.

	               -------------------------------

7. I/O

  1. (Sect. 7) How do I read a file containing ASCII numbers?

     [*] There are several ways to do this. Here is one way. Let's assume
     your file is called "C:\work\mydata.txt" and it contains lines like:

	 135   7512   3659814  328   1 54829
	 68522 19982810  38

     i.e. lines contain several ASCII strings that are numbers separated by
     spaces.
     The code fragment is as follows:

     //  Open the file with
     RandomAccessFile f = new RandomAccessFile("c:\\work\\datafile.txt", "r");

     // read an entire line from it
     String s= f.readLine();

     // get some methods to break up a line into tokens
     StringTokenizer st = new StringTokenizer(s);

     // extract the next int from the line
     i = Integer.parseInt(st.nextToken());

     We use a RandomAccessFile because that supports the readLine() method
     directly. An alternative would be to instantiate a FileReader, and wrap
     a BufferedReader around it. Putting it all together, including the
     exception handling in the event the file is missing, the code looks
     like:

     import java.io.*;
     import java.util.*;
     public class c  {
	 public static void main(String args[]) {
	   try {
	     RandomAccessFile f = new RandomAccessFile
	                                     ("datafile.txt", "r");
	     String s;
	     while ( (s=f.readLine()) != null )  {
	         System.out.println("read: "+s);

	         StringTokenizer st = new StringTokenizer(s);
	         int i=0;
	         while (st.hasMoreTokens()) {
	            i = Integer.parseInt(st.nextToken());
	            // i now holds the next int on the line
	            // could also use Double.parseDouble(), etc.

	            System.out.print(" "+ i);
	         }
	         System.out.println();
	     }

	   } catch (Exception e) {System.out.println("Excpn: "+e); }
	   // file I/O, from book "Just Java" by Peter van der Linden
	 }
     }

     See also the next question on how to read data interactively.

  2. (Sect. 7) How do I read a String/int/boolean/etc from the keyboard?

     [*] The easiest way is to pick up the source for the 100% pure Java
     class EasyIn from http://www.afu.com/ (same place as this FAQ). Compile
     it with your code and use it like this:

     EasyIn easy = new EasyIn();

     int i = easy.readInt(); // gets an int from System.in
     boolean b = easy.readBoolean(); // gets a boolean from System.in
     double d = easy.readDouble(); // gets a double from System.in


     ... etc.

     EasyIn is free, comes with source, and you can do what you like with
     it, including improve it, and send me back the results.

     If, instead, you want to "roll your own" code (why?!), in JDK 1.0.2

     java.io.DataInputStream in = new java.io.DataInputStream(System.in);
     String s = in.readLine();


     One way in JDK 1.1:

     java.io.BufferedReader in =
      new java.io.BufferedReader( new InputStreamReader(System.in));

     String s = in.readLine();


     Once you have the token in a String, it is easy to parse it into one of
     the other types, as shown earlier in the FAQ. Yes, it is bone-headed,
     as it makes the simplest case of keyboard I/O unnecessarily
     complicated. A bug was filed with Javasoft to record this problem, but
     don't count on this being fixed any time soon.

  3. (Sect. 7) Why do I have trouble with System.out.println()? Check the
     spelling. The last two characters are the letters "ell enn" not "one
     enn".

     The name of the method stands for "print line", since it prints a
     String and goes to the next line, rather than staying on the same line
     as System.out.print() does. Yes, the name is yet another Java naming
     inconsistency, since the input equivalent is readLine(), not readln().

  4. (Sect. 7) How do I write to the serial port on my PC using Java?

     [*] There is a platform-independent serial port API introduced in JDK
     1.2. You can download the documentation by registering with the Java
     Developer Connection (it's free, http://java.sun.com) and browsing
     http://java.sun.com/jdc/earlyAccess/communications.html.

     For systems prior to JDK 1.2, read on. At least two companies have
     written a library to drive the port. See
	o http://www.sc-systems.com has a library for Windows 95, WindowsNT,
	  OS/2, Macintosh PPC, Solaris Sparc, Linux x86, FreeBSD x86, HP/UX
	  PA-RISC, and possibly others too.
	o http://www.cd.com/portio
	o In addition, there is a Unix serial port utility available with
	  source at http://jarvi.ezlink.com/rxtx/ It's free under the GPL,
	  and works on Linux, Irix, Solaris, Windows 95, and NT.

     While not helpful to typical home users, there is an alternative
     portable COM port solution for Java 1.1 and even 1.0. Buy your COM
     ports in the form of "terminal servers". Using a COM port is now as
     easy as connecting to it with a Socket. Port parameters can be changed
     programatically using SNMP for most terminal servers (but this is never
     necessary when a modern modem or other fixed-rate equipment is
     attached). Any networked box can serve as a terminal server - even
     Win95 - with a simple native server application for that box, but
     buying an actual firmware based hardware box is much easier.

     Furthermore, your Win95 native applications can now share the COM ports
     (and any attached modems) via a Win95 product called "Dial-out IP" at
     http://www.tactical-sw.com/.

     If the port exists as a pathname in the filesystem, you can open it as
     a file and read/write. You can also print text this way by writing to
     "prn" or "lpt1" on a pc, and "/dev/something" on Unix. Writing a
     formfeed at the end of the file is essential on Windows 95. Here is
     some sample code:

     // class that opens the printer as a file
     // and writes "Hello World" to it

     import java.io.*;
     public class lpt {
	 public static void main (String[] argv) {
	     try {
	         FileOutputStream os = new FileOutputStream("LPT1");
	         //wrap stream in "friendly" PrintStream
	         PrintStream ps = new PrintStream(os);

	         //print text here
	         ps.println("Hello world!");

	         //form feed -- this is important
	         //Without the form feed, the text will simply sit
	         // in print buffer until something else gets printed.
	         ps.print("\f");
	         //flush buffer and close
	         ps.close();
	     } catch (Exception e) {
	         System.out.println("Exception occurred: " + e);
	     }
	 }
     }


     If you wish to change the characteristics of the port (e.g. baud rate,
     parity, etc.), not just read/write data, Java currently offers no
     portable way to do this. You will need to use one of the packages
     mentioned above or some native code or a system command.

  5. (Sect. 7) How do I append to a file?

     [*] There are two ways. JDK 1.1 introduced new constructors for two of
     the output classes that allowed you to set a boolean flag:

     public FileWriter(String fileName, boolean append) throws IOException
     public FileOutputStream(String name, boolean append) throws IOException


     Another way is to do this:

     RandomAccessFile fd = new RandomAccessFile(file,"rw");
     fd.seek(fd.length());


     Then write using fd. Note that the latter method does not take
     advantage of the "append" mode present in many operating systems (such
     as all Unixes). Such a difference may make a difference with multiple
     processes or threads appending to the same output file. This can happen
     frequently, even if not intended by the programmer, e.g. with logfiles
     in multitasking environments.

  6. (Sect. 7) Is it possible to lock a file using Java ?

     [*] JDK 1.2 introduces the ability to lock a file (indirectly) using
     the File class. Use createTempFile() with delete on exit. Prior
     releases of Java do not feature an API to lock a file or regions within
     a file. Code that needs to do this must take one of four approaches:
       1. Implement an advisory locking scheme using features that Java does
	  have (synchronized methods). This allows you to lock files against
	  use by other Java code running in the same JVM.

       2. Use the atomic operation File.createNewFile(), and mark it as
	  deleteOnExit(). Have all processes (Java and non-Java) follow the
	  same protocol: if the create operation succeeded, you have the
	  lock. To give up the lock, you either delete the file or exit the
	  JVM.

	  Note that this may fail if the file is remotely mounted using NFS
	  version 2. (There's a window of opportunity bewteen the LOOKUP to
	  see if it's already there, and the CREATE if it's not). However,
	  NFS version 3 can guarantee exclusive create of remotely mounted
	  files.

       3. Make calls to native code to issue the locking ioctls. This
	  approach is not portable, but gives you a shot at having your
	  locks respected by legacy code in non-Java programs using standard
	  locking ioctls.

       4. Push the work to a central server. Since socket connection
	  requests arrive in a single queue on the server, this can be used
	  to serialize lock requests. There might be some merit in copying
	  the NFS lockd protocol for a general approach. Rolling your own
	  simple version for a specific application is pretty easy. A
	  database would be better off locking records or fields, not byte
	  offsets. In theory, the server socket approach would make it
	  easier to perform automatic cleanup of a lock on abrupt VM process
	  failure, e.g. by asking "are you still alive?" to the lock holder
	  occasionally.

  7. (Sect. 7) How do I make the keyboard beep in Java?

     [*] In JDK 1.1, java.awt.Toolkit has the method beep(). The pre-1.1
     alternative of

     System.out.print("\07");
     System.out.flush();

     (the ASCII BEL character) doesn't work on Macs, but does on some other
     platforms. Java doesn't support the C abstraction of '\a' for an alert
     character.

  8. (Sect. 7) How do I execute a command from Java? How do I do I/O
     redirection in Java using exec()?

     [*] See the answer to Question 18.7.

  9. (Sect. 7) How do you do file I/O from an applet?

     are restricted from doing certain operations, including I/O. This
     prevents rogue applets from sending out your private data, or deleting
     it. A trusted (signed) applet can perform these operations (JDK 1.1
     on).

     The simplest approach for server-side I/O is to use the Linlyn class
     available from http://www.afu.com. This is free software under the GNU
     license, and uses FTP to move files between an applet and the server.
     It is suitable for low-volume non-critical use like keeping a
     high-score file. The Linlyn class has a very simple application
     programmer interface.

	o The following suggestion is for server-side input.

	  You can read a file on the server if you can create a URL
	  referencing the file. Then open a stream, then use any of the
	  stream-based methods to read.

	  This allows reading but not writing. It requires an http daemon
	  running on the server, which will usually be the case.

	  try{
	     URL url = new URL("http://somewhere.com/test.txt");
	   // or URL url = new URL( getDocumentBase(), filename);
	     BufferedReader in = new BufferedReader(
	                           new InputStreamReader(
	                              url.openStream() ) );
	     String s = in.readLine(); //read till you get a null line.
	     } catch(MalformedURLException e){
	             System.out.println("URLException:"+e);
	     } catch(IOException e){
	             System.out.println("IOException:"+e);
	     }
	  }


	  You cannot write a file on the server this way.
	o The following suggestions are for server-side output.

	  It absolutely requires the cooperation of the server to allow an
	  applet to write a file to the server. This cooperation may take
	  any of several forms:
	     + FTP server
	     + File server (webnfs or custom written)
	     + Listening on a socket for data from applets
	     + CGI script
	     + Java RMI (remote method invocation)
	     + JDBC process

	  In particular:
	     + FTP code. Use the Linlyn class mentioned above.
	     + WebNFS. This is an evolution of the NFS (Network File System)
	       to make file resources visible in browsers. More information
	       at http://www.sun.com/webnfs
	     + Open a socket back to the server and read/write the data.
	       Have a process on the server that listens for socket
	       connections from applets and does the requisite I/O. This
	       does I/O on the server.
	     + Or use a CGI script or servlet on the server to write when
	       browsed.
	o The following suggestions are for client-side I/O.

	  Use a trusted applet (see section on security). This will permit
	  local I/O without any of the restraints mentioned above. In this
	  regard, the appletviewer and many other browsers regard applets
	  loaded from a local filesystem (rather than across the net) as
	  being more trustworthy, and perhaps even allowed to do I/O.
	o The simplest form of output is probably for the applet to connect
	  to the mailserver port on the server, and prompt the user to enter
	  his email address. Then email him the data to save locally if he
	  wishes. If a small amount of data he can later enter it by
	  cut-and-paste into the applet when he next invokes it.
	o Or use a browser that has a security policy that is configured to
	  allow file I/O (such as Sun's appletviewer).
	o Read this article
	  http://www.javareport.com/html/features/archive/9802/somers.shtml
	  for an introduction to the basics.

 10. (Sect. 7) I used a C program to write a binary file. When I instantiate
     a DataInputStream on the file in Java, and try to readInt, I do not get
     the correct numbers. Why is this?

     [*] Java does everything in network byte order (big-endian order), as
     do many computers including Motorola, and SPARC. The Intel x86 uses
     little-endian order in which the 4 bytes of an int are stored least
     significant first. Rearranging the bytes on the way in will get you the
     results you need. This is only necessary when the file was written by a
     non-Java program on a little-endian machine such as a PC.

     The following code will byte-swap little-endian integers into network
     standard order:

     public int swap(int i) {
	 int byte0 = i & 0xff;
	 int byte1 = (i>>8) & 0xff;
	 int byte2 = (i>>16) & 0xff;
	 int byte3 = (i>>24) & 0xff;
	 // swap the byte order
	 return (byte0<<24) | (byte1<<16) | (byte2<<8) | byte3;
     }


     Alternatively, the following code assembles bytes from a byte array
     that is in big-endian order (as used by Java) into an int:

     byte[] bytes = ... // whatever
     int start_index = ... // wherever

     int value = 0;
     for ( int i = start_index; i < start_index+4; ++i ) {
	 value = ( value << 8 ) | ( bytes[i] & 0xFF );
     }


     If the bytes are in little-endian order, just change the "for"

     for ( int i = start_index+3; i >= start_index; --i )


     And this code will assemble a double that has been written in reverse
     byte order:

       byte[] gnol = new byte[8];
       stream.read(gnol);

       long l = (
	          ( (gnol[7] & 0xff) << 56) |
	          ( (gnol[6] & 0xff) << 48) |
	          ( (gnol[5] & 0xff) << 40) |
	          ( (gnol[4] & 0xff) << 32) |
	          ( (gnol[3] & 0xff) << 24) |
	          ( (gnol[2] & 0xff) << 16) |
	          ( (gnol[1] & 0xff) <<  8) |
	            (gnol[0] & 0xff)
	        );

       double d = Double.longBitsToDouble(l);


 11. (Sect. 7) How do I make I/O faster? My file copy program is slow.

     [*] This is the purpose of BufferedInputStream. It is a flaw in Java
     that buffered I/O is not the default, with a flag or different
     constructor to turn it off. I/O is the second worst designed package in
     Java, after the Date class. ,

 12. (Sect. 7) How do I do formatted I/O of floating point numbers?

     [*] Use the class java.text.NumberFormat.

     Or use http://www.newbie.net/sharky/lava/. Or use Cay Horstmann's
     http://www.horstmann.com/corejava/Format.java
     Although many utilities claim to handle all varieties of C's printf, as
     far as has been found, this is the only one to correctly handle the
     equivalent of %e in printf.

     See also the standard packages java.text.DecimalFormat and
     java.text.NumberFormat

 13. (Sect. 7) How do I read numbers in exponential format in Java?

     [*] The program below (written by Steve Chapel) uses StreamTokenizer to
     read data from the standard input and recognizes doubles in exponential
     format (e.g. -1.23e-45).

     import java.io.*;

     public class ReadExponential {
	 public static void main(String argv[]) {
	     DataInputStream in = new DataInputStream(System.in);
	     StreamTokenizer st = new StreamTokenizer(in);
	     try {
	         while (st.nextToken() != StreamTokenizer.TT_EOF) {
	             switch (st.ttype) {

	case StreamTokenizer.TT_NUMBER:
	          double num = st.nval;
	          int exp = 0;
	          st.ordinaryChars('\0', ' ');
	          st.nextToken();
	          st.whitespaceChars('\0', ' ');
	          if (st.ttype == StreamTokenizer.TT_WORD &&
	              Character.toUpperCase(st.sval.charAt(0)) == 'E') {
	              try {
	                 exp = Integer.parseInt(st.sval.substring(1));
	              } catch (NumberFormatException e) {
	                 st.pushBack();
	              }
	          } else if (st.ttype < 0 || st.ttype > ' ')
	              st.pushBack();
	          System.out.println("Num " + num * Math.pow(10, exp));
	          break;
	 case StreamTokenizer.TT_WORD:
	          System.out.println("Word " + st.sval);
	          break;
	 default:
	          System.out.println("Char '" + (char) st.ttype + "'");
	          break;
	      } // end switch
	  }  // end while
	} catch (IOException e) {
	  System.out.println("IOException: " + e);
	}
      } // end main
     }


 14. (Sect. 7) I'm trying to read in a character from a text file using the
     DataInputStream's readChar() method. However, when I print it out, I
     get ?'s.

     [*] Remember that Java characters are 16-bit Unicode characters, while
     many hosts systems store characters as 8-bit ASCII characters.
     Therefore, to read individual chacters from a text file, you need to
     ensure the proper conversion. The proper way to do this is to use an
     InputStreamReader, which converts from 8 to 16 bit streams:

     FileInputStream fis = new FileInputStream("myfile.txt");
     InputStreamReader isr = new InputStreamReader(fis);
     char c3 = (char) isr.read();

     The less-favored way (because it is not so portable, as the encodings
     translation is not done) is just to read a byte and cast it into a
     character:

     FileInputStream fis = new FileInputStream("myfile.txt");
     DataInputStream dis = new DataInputStream(fis);
     char c1 = (char) dis.readByte();


 15. (Sect. 7) How do I delete a directory in Java?

     [*] JDK 1.0 did not support directory removal. JDK 1.1 supports
     directory removal with the method:
	  public boolean delete() in class java.io.File

     Make sure you don't have any open streams in the directory you're
     trying to remove. Do a close() on all streams, even if the underlying
     file is gone.

 16. (Sect. 7) How do I tell how much disk space is free in Java?

     [*] There currently aren't any good Java APIs for system introspection.
     There is no Java way to control processes, or look at system resources.
     You can use Runtime.getRuntime().exec() to do "df" on unix or "dir" on
     Windows right now.

     Alternatively, check out JConfig:
     http://www.tolstoy.com/samizdat/jconfig.html
     JConfig is a cross-platform library that fills in many of the gaps in
     the core Java API, and makes it possible to work with files, processes,
     file types, video monitors, etc. in a much more Windows- and
     Mac-friendly manner.

 17. (Sect. 7) How do I get a directory listing of the root directory C:\ on
     a PC?

     [*] The obvious approach of calling File.list("C:\"); does not work.
     There are two reasons why this fails. First, slash is an escape
     character in Java, so if you want a literal slash, you have to repeat
     it. Second, you need to give the name of the directory, i.e. dot.
     Putting this together, either of the following calls will work

     File.list("C:\\.");


     or

     File.list("C:/.");


     Note: a file separator of "/" works just as well as "\" in most Windows
     programs and library calls. It is an artifact of DOS's origin's as a
     ripped-off port of CP/M. When Microsoft bought the rights to DOS from
     Seattle Computer Products (what, you didn't know Microsoft didn't
     develop DOS? They didn't even own the rights to DOS at the time the
     contracted with IBM to supply DOS for the PC) they were buying software
     which was an unauthorized port of the CP/M operating system.

     CP/M didn't have directories, so it didn't use pathname separators. The
     forward slash "/" was already used for giving options to CP/M commands,
     so "\" was pressed into service as the DOS pathname separator, but the
     DOS shell was taught to understood "/" for compatibility with other
     OS's. See also JConfig in Q6.15.

 18. (Sect. 7) What is the difference between the various ZIP formats: ZIP,
     GZIP, and PKZIP?

     [*] Zip is an archive file format, popularized on PCs, that contains
     multiple compressed files.
     GZIP comes from Gnu. It is essentially a one file subset of the Zip
     format. You can't put a whole directory into a GZIP archive, just a
     single file. It's intended for compressing a tarball of many files.
     PKZIP is a set of commercially available programs that create Zip
     files. All three use the deflate compression format, which is based on
     the LZ77 algorithm. This compression is also used by the ZLIB library
     and hence the PNG graphics file format (which uses ZLIB). PNG -
     Portable Network Graphics - provides a patent-free replacement for GIF
     and TIFF.

     An alternative compression technology, LZW compression, is encumbered
     by Unisys's patent. LZW is used in GIF files and by the Unix compress
     command. Luckily, as well as being free from patent restrictions, LZ77
     also gives better compression than LZW. LZW is the initial letters of
     the last names of the three computer scientists who developed the
     algorithm (Lempel, Ziv, Welch).

     The basic classes (all in java.util.zip) that read LZ77 Zip format are
     Deflater and Inflater. These are used by the stream classes
     DeflaterOutputStream and InflaterInputStream. The java.util.zip classes
     GZIPInputStream and ZipInputStream inherit from InflaterInputStream.

     PKZIP is a commercial program for DOS, Windows, and OS/2, sold by
     PKWARE Their FAQ, at http://www.pkware.com/zipgfaq.html, specifically
     says
	  "Because PKWARE has dedicated the .ZIP file format to the public
	  domain, it is possible for other people to write programs which
	  can read .ZIP files. NOTE THAT THE PKZIP, PKUNZIP, PKSFX PROGRAMS
	  AND THEIR ASSOCIATED SOURCE CODE AND SUPPORT PROGRAMS ARE THE
	  EXCLUSIVE PROPERTY OF PKWARE INC. AND ARE NOT PUBLIC DOMAIN
	  SOFTWARE PROGRAMS.

     The "other people" PKZIP's FAQ refers to is the InfoZIP project, a
     group of public-minded programmers spread over the world producing free
     software that works on most ANSI C compilers and platforms. See
	  http://www.cdrom.com/pub/infozip/.

     Jar files are in ZIP format, but are not as complete as a full
     filesystem archive format since file permissions are not saved. Some
     versions of WinZip are known to be inadequate for processing the full
     PKZIP format. Use InfoZIP instead.

 19. (Sect. 7) How can I use characters other than ASCII in Java?

     [*] Search for the article titled "Adding Fonts to the Java Runtime" or
     visit:
     http://java.sun.com/products/jdk/1.2/docs/guide/internat/fontprop.html

     The article explains how to add fonts to Sun's JDK, using the
     font.properties file. [If anyone has summarised the information, please
     send it in].

 20. (Sect. 7) I did a read from a Buffered stream, and I got fewer bytes
     than I specified.

     [*] This is the way that BufferedInputStream works up to and including
     the current release. The behavior is so unintuitive that it really
     represents a bug. Javasoft has "resolved" the bug by writing comments
     in the program so that the broken behavior is in the range of legal
     outcomes. Ugh.

     When you instantiate a buffered input stream, you can specify the size
     of buffer it should use. Let's call this the internal buffer. When you
     call read() you can say how many bytes to read. Let's call this the
     request. If the request is smaller than the internal buffer and not a
     multiple of the internal buffer, then the last read returns only the
     odd bytes left in the internal buffer! The more reasonable and
     intuitive behavior would be for the internal buffer to be refilled, so
     that the whole request can be granted.

     For example, if you create a BufferedInputStream with an internal
     buffer of 1000 bytes, and try to read 512 byte chunks, your first read
     will return 512 bytes, but your second read will only return
     (1000-512), or 488, bytes. (Assuming that the file has at least that
     many bytes in it). The following code illustrates the problem.

     // troubleshooting by Tov Are Jacobsen
     import java.io.*;
     class filebug {
	 public static void main(String args[])
	               throws FileNotFoundException, IOException  {
	 BufferedInputStream bis =
	    new BufferedInputStream(
	    new FileInputStream("test.txt"), 1000 );
	 byte[] buf = new byte[2000];
	 int numread;
	 System.out.println( "Available: "+bis.available() );
	 while (true) {
	     numread = bis.read(buf,0,512);
	     if (numread<0) break;
	     System.out.println( "got "+numread
	                        +", avail:"+ bis.available());
	 }
       }
     }


     Of course, a valid reason for getting less than you asked for is that
     you asked for more data than is actually available in the Stream, e.g.
     you requested 512 bytes from a file that only contains 40 bytes. In
     general, there are no guarantees about how much data is returned for a
     given buffered input stream read request. To avoid this problem, push a
     DataInputStream on top of your buffered stream. Then you can call
     readFully(), which will do what you want.

     A similar "got less than I asked for" occurs when reading a socket.
     Network protocols frequently packetize data and send it across in
     bursts. Nothing is lost of course, and you are always told how many
     bytes you actually got. You will get the remaining bytes on a
     subsequent read. This happens regardless of the language used. Be sure
     to check the "amount of data returned" when using the read(byte[], int,
     int) method of BufferedInputStream, or when reading from a socket.

     Another problem with java.io.InputStream.read(byte[], int, int) is that
     it catches and ignores IOExceptions. Instead, these exceptions should
     be passed on to the caller. Ace programmer Jef Poskanzer, jef@acme.com,
     has a version to do this at
     http://www.acme.com/java/software/Acme.Utils.html. See Jef's read() and
     readFully() routines.

 21. (Sect. 7) How do I redirect the System.err stream to a file?

     [*] You cannot assign a new FileOutputStream to System.err, as it is
     final. Instead use the System.setErr() library call, like this:

     FileOutputStream err = new FileOutputStream("stderr.log");
     PrintStream errPrintStream = new PrintStream(err);
     System.setErr(errPrintStream);


     This was introduced with JDK 1.1. There is also a corresponding setIn()
     for redirecting standard in, and a setOut() for standard out.

     Note that you will get a compiler warning about a deprecated construct
     when you do this. PrintStreams are deprecated in favor of PrintWriters,
     which handle Unicode properly. The PrintStream is marked as deprecated
     by marking all its constructors as deprecated. There is no way to
     create the PrintStream needed to redirect System.err or System.out
     without triggering the deprecated warning.

 22. (Sect. 7) What are the values for the Unicode encoding schemes?

     [*] If you review the String constructor with this signature

	 String(byte[] bytes, String encoding)

     you can see that one argument is a value for the encoding scheme that
     the conversion of 8-bit bytes to 16-bit Unicode chars is to use.

     There are three: "Unicode", "UnicodeBig" and "UnicodeLittle". The first
     one expects the first two bytes of your data to be a Byte Order Mark,
     FEFF or FFFE, which specifies whether the data is in little-endian or
     big-endian order. If there isn't a BOM but you already know the
     endianness, you can use "UnicodeBig" or "UnicodeLittle" directly.

     There is also a Sun document at
     http://java.sun.com/products/jdk/1.1/docs/guide/intl/encoding.doc.html
     with some related information (not much).

     There is another Sun document at
     http://java.sun.com/products/jdk/1.1/intl/html/intlspec.doc7.html which
     shows the table of encodings. There is a new system property called
     "file.encoding" which translates between codes known to Java like
     "Cp1252", and locale encoding names like "Windows Western Europe /
     Latin-1"

 23. (Sect. 7) Is there a way to read a char from the keyboard without
     having to type carriage-return?

     [*] You can do this in a GUI (e.g. in a text component). There is no
     pure Java way to do character-by-character I/O without using a GUI.

	               -------------------------------

8. Core Libraries

  1. (Sect. 8) I can't seem to change the value of an Integer object once
     created.

     [*] Correct. Integer (Float, Double, etc) are intended as an object
     wrapper for a specific value of a number, not as a general-purpose way
     of shipping a primitive variable around as an Object. If you need that
     it's easy enough to create: class General { public int i; }

  2. (Sect. 8) How do I print from a Java program?

     [*] Use the Toolkit.getPrintJob() method

     Component c = this.getParent();
     while (c!=null && !(c instanceof Frame))
	 c=c.getParent();
     // With a JComponent use   c=getTopLevelAncestor();

     PrintJob pj = getToolkit().getPrintJob((Frame) c, "test", null);
     Graphics pg = pj.getGraphics();
     printAll(pg);
     pg.dispose();
     pj.end();


     This feature was introduced with JDK 1.1. A common place to put this is
     in the code that handles a button press. Printing from an untrusted
     applet is subject to a check from the SecurityManager.

     The JDK 1.1 printing API is more a screen hardcopy facility than a full
     blown publishing and illustration hardcopy API. JDK 1.2 offers a more
     full-featured printing API.

     If you simply want to print text, then write it to a file and print the
     file. Or open a filename that corresponds to the printer. On Windows,
     that is "LPT1" and the code looks like:

     try {
	 FileOutputStream fos = new FileOutputStream("LPT1");
	 PrintStream ps = new PrintStream(fos);
	         ps.print("Your string goes here");
	         ps.print("\f");
	         ps.close();
     } catch (Exception e) {
	 System.out.println("Exception occurred: " + e);
     }


     The final formfeed is needed by windows to start the printjob.

  3. (Sect. 8) What are the properties that can be used in a PrintJob?

     [*] The properties are
	o awt.print.destination - can be "printer" or "file"
	o awt.print.printer - printer name
	o awt.print.fileName - name of the file to print
	o awt.print.numCopies - obvious
	o awt.print.options - options to pass to the print command
	o awt.print.orientation - can be "portrait" or "landscape"
	o awt.print.paperSize - can be "letter","legal","executive" or "a4"
     The defaults are destination=printer, orientation=portrait,
     paperSize=letter, and numCopies=1.

     You can search for info like this by joining the Java Developer
     Connection (it's free) at http://java.sun.com/jdc.

     and doing a search for "PrintJob".

  4. (Sect. 8) Is there any package in Java to handle HTML?

     [*] See the answer to Question 13.14.

  5. (Sect. 8) Why don't Dialogs work the way I want them to?

     [*] Modal dialogs (dialog windows that stay up until you click on them)
     are buggy in many browsers and in the 1.0.2 JDK. One bug is that the
     dialog is not necessarily put on top when it is displayed. Most of the
     modal dialog bugs are fixed in JDK 1.1.

  6. (Sect. 8) Where can I find information about the sun.* classes in the
     JDK?

     [*] You're not supposed to. Those classes are only to support functions
     in the java.* hierarchy. They are not part of the API, and won't be
     present in Java systems from non-Sun vendors. Some people have
     reverse-engineered the code and published an API for these classes but
     you use it at your own risk, and it may change without warning.

     Worst of all, those programs will not have the portability of true Java
     but will only run on Sun JDKs. For the same reason you shouldn't use
     classes outside the java.* packages when using JDKs from other vendors.

     If you still insist on going ahead, check these URLs:
     http://java.sun.com/products/api-overview/index.html
     http://www.parmly.luc.edu/javaudio/
     http://www.users.interport.net/~mash/javamidi.html

  7. (Sect. 8) How do you read environment variables from with a Java
     program?

     [*] Environment variables are not used in Java, as they are not
     platform-portable. The Mac doesn't have environment variables, for
     example. A Windows 95 application not started from a DOS window does
     not have environment variables. Use properties instead. It was a design
     error in JDK 1.0 that programmers had to set the CLASSPATH environment
     variable. This should have been set in a property file

     Create your own properties file (see java.util.Properties) or specify
     them with the -D option when you invoke the interpreter or JRE.
     Additionally, on some systems you can set a property from the command
     invocation line like this:

     java -Dfoo=$foo MyClass (Unix)

     or

     java -Dfoo=%foo% MyClass (Win95/NT)

     This sets the "foo" property to the value of the environment variable
     foo, and makes it available in the System properties. Make sure you do
     not leave any spaces after the -D or around the = sign. Inside the
     program you get the value with:

     String env = System.getProperty("foo");

     More simply, just put the environment variable on the command line and
     read it as arg[0].

     java MyClass %FOO% ; Win32
	 java MyClass $FOO ; Unix


     Finally, you could execute a Runtime process to get the environment
     variables if you are on a platform that has them.

     import java.io.*;
     import java.util.Properties;

     public class Main {
	 public static void main(String[] argv) {
	     Properties envVars = new Properties();

	     try {
	       envVars.load(   // use "set" on Windows
	             Runtime.getRuntime().exec("/bin/env").getInputStream());
	     } catch (Throwable t) {t.printStackTrace();}

	     System.out.println("\n\n" + argv[0]
	                      + " = <" + envVars.get(argv[0]) + ">");
	 }
     }

     This is not a Pure Java approach as it builds platform-specific
     knowledge into the program. See Question 10.6 for more details. On
     Unix, the command that prints environment variables is "/usr/bin/env".
     On Windows95, it is "set"

  8. (Sect. 8) How do I get Java talking to a Microsoft Access database?

     [*] Use the JDBC-ODBC bridge. It is not especially challenging to set
     up, but it does require painstaking attention to detail. There is a
     step-by-step example in the van der Linden text "Just Java" mentioned
     in the sponsorship section of this document.

     Note that the Microsoft version of the Java kit does not support
     JDBC-ODBC access because it uses a non-standard native code interface.
     The JDBC FAQ can be found at
     http://java.sun.com/products/jdbc/jdbc-frequent.html

  9. (Sect. 8) I can't seem to change the current working directory.

     [*] Correct. This missing functionality is an oversight that we hope
     will be corrected in the future. The bug id is 4156278, please feel
     free to join the JDC, and vote to have this (or any other) fixed.
     Changing the user.dir property merely changes the text property, not
     the underlying reality that it is supposed to reflect.

     There are several workarounds.
	o Run your java app from a .bat or .sh file and do the "cd" in that
	  (before you run your java app), assuming that all the external
	  processes you need to exec can be run from the same directory.
	o Do: exec("cd /home/wherever; externalApp.exe") on unix, (there
	  doesn't seem to be an equivalent on NT).
	o Instead of running the .exe directly, run (or write on the fly) a
	  .bat or .sh file that does the cd and then runs the .exe for you
	  (this could well create trouble with getting back the correct
	  return status)

 10. (Sect. 8) How do I create a Vector of ints?

     [*] ints are primitive types and hence can't be stored by the Vector
     class, which stores objects. You'll need to wrap the ints. Try this:

     int i =7;
     Vector holdsInts = new Vector(5,1);

     holdsInts.addElement(new Integer(i));
     int j = ((Integer)holdsInts.elementAt(0)).intValue();


 11. (Sect. 8) I have several worker threads. I want my main thread to wait
     for any of them to complete, and take action as soon as any of them
     completes. I don't know which will complete soonest, so I can't just
     call Thread.join on that one. How do I do it?

     [*] You need to use the wait/notify mechanism to allow any of the
     worker threads to wake up your main thread when the worker has
     completed.

 12. (Sect. 8) How do I get random numbers?

     [*] If you just need a quick random double between 0.0 and just less
     than 1.0

     double myrandom = Math.random(); // [0,1)


     The notation "[0,1)" is common math notation for "zero to .9999999 etc"
     The Sun documents say this returns 0.0 to 1.0, but inspection of the
     source shows they are wrong. However, due to the inherent inaccuracies
     of floating point arithmetic, multiplying N by 0.999999 etc can result
     in an answer of N, not N * .999999. So watch out when N is big.

     JDK 1.2 adds another version of nextInt that accepts a parameter for
     returning ranged random numbers.

     Where things get trickier is when you use JDK 1.1 and want an int in a
     certain range, say 1 to 6 to simulate the throw of a die or 1 to 52 to
     represent a playing card. Class Random has a nextInt method that will
     return any integer:

     import java.util.Random;
     Random r = new Random();
     int i = r.nextInt();


     However, that has an (almost) 50% chance of being negative, and it
     doesn't come from the right range. So you just take the abs() value and
     then mod it into the right range:

     int dice_throw = 1 + Math.abs(i) % 6;


     Except, the abs() method fails gracelessly in the presence of the
     Integer.MIN_VALUE (it returns the same, negative, result!). So it is
     better to AND to get the non-negative value: In general, to get a
     random int between high and low limits (inclusive):

     java.util.Random r = new java.util.Random();
     int j = (r.nextInt() & Integer.MAX_VALUE) % (high-low+1) + low;


     The sentence above states "(almost) 50% chance" because there is one
     more value in the negative integers than in the positive integers in
     two's complement arithmetic as used by Java. For most purposes, the
     bias introduced will be insignificant, but we "and" the nextInt() to
     convert it to zero. Sure, it's unlikely to occur, but you don't want
     the reactor going critical just because you missed this case while
     testing.

     A worse problem is that with the algorithm used, the low order bits are
     significantly less random than the higher order bits. And the low order
     bits are precisely the ones you get when you do a (mod 2^n) operation.
     You may consider using java.security.SecureRandom which provides much
     better randomness by using a Cryptographic hash, although it is much
     more expensive to compute.

 13. (Sect. 8) What does "deprecated" mean? I got this in a compiler error
     message.

     [*] The compiler will flag a now-obsolete API as "deprecated". The word
     means "officially disapproved of". Compile again with the
     "-deprecation" option to see what is deprecated. In almost all cases,
     the old API has been replaced by a new one. Update your code to use the
     new one.

     An example of using a deprecated API is calling component.size(). That
     has been replaced by component.getSize().

 14. (Sect. 8) Where/why should I use the Enumeration interface?

     [*] It's a very convenient way to step through some of the library data
     structures, such as HashTable, Vector, and ZipFile. It is thread safe.
     If you're looking at an element in one thread while another thread is
     trying to delete it, it won't half vanish.

     Here's how you might look at every file in a ZIP file:

     ZipFile z = new ZipFile("foo.zip");
     Enumeration e = null;
     for (e=z.entries(); e.hasMoreElements(); ) {
	ZipEntry ze = (ZipEntry)e.nextElement();
	System.out.println("got " + ze.getName() );
     }


     And here's how you might look at all the tokens in a String:

     StringTokenizer tokens =
	 new StringTokenizer (SomeArbitraryString, "\n", false);

     Enumeration enum = tokens.elements();
     while enum.hasMoreElements()
	 System.out.println(enum.nextElement());

     You should look for opportunities in your own data structures to
     implement Enumeration anywhere where the structure has repeated
     elements.

 15. (Sect. 8) Which version of WinZip is compatible with java.util.zip?

     [*] You need WinZip version 6.2 or later. Version 6.1 or earlier is not
     good enough. WinZip can be downloaded from
     http://www.winzip.com/download.cgi. The pkzip software works fine.
     Infozip is better than WinZip because it lacks the winzip "feature" of
     failing to recreate directories unless given a special option. Use
     Infozip.

 16. (Sect. 8) How can Java access other fonts on my system?

     [*] You do it by editing the fontnames in the font.properties file in
     the lib directory of your JDK release. Watch out for program
     portability when you do this.

     For more details, check the website
     http://www.alumni.caltech.edu/~dank/javafont.htm and the JavaSoft site
     at http://java.sun.com/products/jdk/1.1/docs/guide/intl/fontprop.html
     They have lots of information on this.

 17. (Sect. 8) How can I trap Control-C in Java?

     [*] Control-C is used on some OS's to break into a running program
     interactively and terminate it. On Unix Control-C is sent to the
     process as a signal. If a C program declares a handler for that signal,
     the program will be able to continue even if Control-C is sent to it.
     Control-C is not a Java concept, and there is no way to do this in pure
     Java. You can write the signal handler in C however, and impose the
     handler by calling the C routine through the Java Native Interface.

 18. (Sect. 8) How do you parse commandline arguments to a Java program?

     [*] Perhaps surprisingly, commandline arguments are not encouraged, as
     they make a program not 100% pure Java. The reason is that some systems
     like MacOS don't normally have a command line or command-line
     arguments. Consider using properties instead so that your programs fit
     more naturally into the environment.

     If you must use command-line arguments, have them comply with the POSIX
     conventions, i.e. they should
	o use a "-" instead of a "/"
	o be case sensitive, and
	o be concatenatable (-pst == -p-s-t).
     See
     http://java.sun.com/docs/books/tutorial/essential/attributes/_posix.html

     If such arguments are used, it should NOT be up to the invocating
     application (ie java.exe) to propperly parse them. According to the
     getopts routine from gnu, getopts is required to know exactly what the
     usable parameters are before it can properly parse them and create
     argc/argv.

     Because of that, it becomes unduly hard for calling programs such as
     java.exe to properly parse class arguments by themselves. Instead, they
     should create an argc/argv pair (actually a java specific array
     dependant on the way in which the method is called) where the number of
     elements equals the number of text words in the options. Text word
     means a group of ascii characters outside of quotation marks, not
     separated by white space. Once these text words are passed to the
     class, it is up to the class to actually parse them correctly.

     The text words passed to the class can be parsed however the class
     author wishes. It is up to the author to correctly parse the options.
     There are several implementations of getopts which perform such
     parsing, in C, Perl, and Java. You will find one at
     http://www.urbanophile.com/arenn/hacking/download.html#getopt

 19. (Sect. 8) How many threads can I create?

     [*] By default, on a Win32 machine, each ("native") thread gets one MB
     (1024*1024 bytes) of stack space reserved for it. The memory is not
     actually allocated. If it were, you'd run out of memory with dozens of
     threads instead of hundreds. The space needs to be reserved as a
     contiguous block of memory so the stack can grow as needed.

     Under Win32, the max amount of memory is 2GB, which corresponds to
     2,000 threads each reserving 1MB of memory. That's an upper bound; in
     practice you'd run out of other OS resources before running out of
     memory. Each thread has some system resources that will be used to
     manage the thread -- register storage area, thread-local storage, state
     information, exception condition info, etc.

     You should design your programs so that you use threads only where
     necessary. It's almost always a mistake to have one thread per object.
     Successful programs are much more likely to have 5 threads (or fewer)
     than 500.

	               -------------------------------

9. Dates and Times

     Credit to Paul Hill who completely rewrote this section, and to
     the programmers at IBM who implemented much of the Java Date code,
     and reviewed this section of the FAQ for accuracy.

	                       java.util.Date

  1. (Sect. 9) Is Java "Year 2000"-compliant?

     [*] Java is Y2K compliant in release JDK 1.1.6 and later. See
     http://www.sun.com/y2000/cpl.html. Prior to this release there were
     certain corner case bugs that had to be fixed.

     The Date class, as you can see from the discussion, contains more than
     enough resolution to represent dates in this century and the next and
     the last. The SimpleDateFormat when parsing a 2 digit year could cause
     problems; see discussion below.

  2. (Sect. 9) What happen to java.util.Date between JDK 1.0 and JDK 1.1?

     [*] In JDK 1.1 the java.util.Date class was split to provide better
     support for timezones, and internationalization.

     The classes specifially related to dates are summarized below:

	    1. The class Date represents a specific instant in time,
	       with millisecond precision.
	    2. The class TimeZone is an abstract class that represents
	       a time zone offset, and also figures out daylight
	       savings time adjustment.
	    3. The class SimpleTimeZone is the only concrete subclass
	       of TimeZone in the JDK.  It is what defines an ordinary
	       timezone with a simple daylight savings and daylight
	       savings time period.
	    4. The class Calendar is an abstract class for converting
	       between a Date object and a set of integer fields such
	       as year, month, day, and hour.
	    5. The class GregorianCalendar is the only concrete
	       subclass of Calendar in the JDK. It does the
	       Date-to-fields conversions for the calendar system in
	       common use.
	    6. The class DateFormat is an abstract class that lets you
	       convert a Date to a printable string with fields in the
	       way you want (e.g. dd/mm/yy or dd.MMM.yyyy).
	    7. The class SimpleDateFormat is the only concrete subclass
	       of DateFormat in the JDK. It takes a format string and
	       either parses a string to produce a date or takes  a
	       date and produces a string.

     At least one critic has used the term "baroque" when describing the
     complexities of the Java date related classes, but other critics would
     spell that "broke". The good news is that as of JDK 1.2 all of the
     common problems have been corrected and many of the bugs were corrected
     in 1.1.4 and 1.1.6. Even in 1.1.1, you can avoid most of the most
     annoying bugs by always keeping in mind which timezone each class is
     using.

  3. (Sect. 9) Exactly what is a java.util.Date?

     [*] A java.util.Date stores a moment in time as a long integer
     representing the number of milliseconds since 00:00:00 Jan 1, 1970 UTC
     (Coordinated Universal Time). This zero moment is known as the "Epoch".
     This is the same Epoch as is used on Unix systems. Dates earlier than
     the Epoch are represented as negative numbers, counting away from
     1/1/1970.

     The scheme is sufficient to represent dates from 292,269,053 B.C. to
     292,272,993 A.D. (64 bits covers -9,223,372,036,854,775,808 to
     +9,223,372,036,854,775,807 milliseconds. But note that prior to JDK
     1.2, a GregorianCalendar will not accept values earlier than 4716 B.C.

     A java.util.Date is the light-weight object intended to just hold a
     millisecond value. It is used to hold, communicate and store a moment
     in time. Other tasks like creating a formated string, or calculating
     dates are best done using other classes.

  4. (Sect. 9) Does a java.util.Date really represent the true UTC?

     [*] No, but it is close enough for most human time-keeping purposes. On
     most computers, it only represents the time since the epoch as
     converted from the value on the underlying hardware. If you have
     hardware that is synchronized with an atomic clock your time is UTC;
     most hardware assumes a day is 24 hours long, but there have been more
     than 20 leap seconds added to UTC, since the first one was added in
     1972.

  5. (Sect. 9) How do I create a Date object that represents the current
     time?

     [*] The default value of a date object is the current time, so the
     following code creates a date object that contains the current time.

     Date now = new Date();

  6. (Sect. 9) I want to create a string that represents a date in a format
     other than what is returned by java.util.Date.toString() do I have to
     use a Calendar?

     [*] No. Instead of creating a Calendar and pulling out all of the
     appropriate fields and making a string, you could use
     SimpleDateFormat.format() to create a string.

  7. (Sect. 9) Why are all the methods in java.util.Date deprecated?

     [*] Mostly because the original java.util.Date was not completely aware
     of the timezone and "not amenable to internationalization". To make it
     timezone aware and internationalizable would have required adding some
     of the functionality which can now be seen in java.util.Calendar and
     some of the functionality in java.util.DateFormat. If you find the
     combination all of the date related classes complex, just be glad they
     were separated into different classes.

  8. (Sect. 9) I really don't need a internationalizable, timezone aware,
     extra flexible formating set of date classes. Is there anything else I
     can use that stores only a date, and allows me to do some date
     calculations?

     [*]You could consider using the BigDate class written by Roedy Green,
     and available in his very informative glossary (search for BigDate). If
     you want to store the result in a database as a Date or TimeStamp, you
     should read the section below on java.sql.Date.

  9. (Sect. 9) Since the Date( String ) constructor is deprecated what do I
     use instead?

     [*] The best choice is to use SimpleDateFormat.parse() to create a
     java.util.Date object.

     The Date constructor that accepts a string calls Date.parse( String ).
     The Date.parse() function had its own rules for converting 2 digit
     years (it used a 1980 pivot date) and other limitiations which makes it
     of limited value. Other "features" of Date.parse() that are not
     supported in SimpleDate have not been missed by many developers.

 10. (Sect. 9) Since Date(int year, int month, int date) and related

     [*] The constructor GregorianCalendar(int year, int month, int date) is
     the newer replacement. Other choices are the Calendar.set( year, month,
     day ) method. Note that the year in the GregorianCalendar starts at 1
     A.D., not at 1901 like the old Date constructor.


	                        java.util.TimeZone

 11. (Sect. 9) How can I see if my JVM is using the right timezone?

     [*] The following codes displays the ID of the current default
     timezone.

       System.out.println( TimeZone.getDefault().getID() );

 12. (Sect. 9) The value of TimeZone.getDefault is not what I expected. What
     is the problem?

     [*] The value of the default timezone is based on the value of the
     system property "user.timezone". The JVM  is supposed to set this
     value. In releases such as JDK 1.1 the value of user.timezone was often
     not set to anything, so TimeZone.getDefault() used its own built in
     "fallback" value (the default when there is no default value). In later
     JDK 1.1 releases and in JDK 1.2 the setting of the value of
     user.timezone is much better and the "fallback" value is now GMT
     (Greenwich Mean Time). Up until JDK 1.1.3, the fallback value was "PST"
     (North American Pacific Timezone).

 13. (Sect. 9) Do all the standard objects use the same default timezone?

     [*] Not until JDK 1.2. In JDK 1.1, Date.toString() and Calendar used
     the value of TimeZone.getDefault() which could often be undefined (see
     the previous question). In JDK 1.1, The Calendar in a SimpleDateFormat
     was set to the 1st timezone resource for the locale (for the US this is
     PST).

     System.out.println( "Date format TZ = " + TimeZone.getDefault().getID() );
     sdf = DateFormat.getDateTimeInstance( DateFormat.LONG, DateFormat.LONG );
     System.out.println( "Date format TZ = " + sdf.getTimeZone().getID() );
     Calendar cal = Calendar.getInstance();
     System.out.println( "Calendar TZ = " + cal.getTimeZone().getID() );

     When run on a system running JDK 1.1.6, NOT in the North American
     Pacific Time nor in the GMT timezone results in:

     Timezone default = GMT
     Date format TZ = PST
     Calendar TZ = GMT

     This example shows two bugs, the value of user.timezone is undefined,
     so its defaulting to GMT (see discussion of TimeZone.getDefault()) and
     it shows that the DateFormat depends on the 1st locale entry which in
     this case is PST.

     If you don't want the DateFormat to use the Locale timezone, see the
     code provided below.

 14. (Sect. 9) If I explicitly set the default timezone, don't I need code
     to choose between (a) the daylight savings version or (b) the standard
     version of a timezone?

     [*] No. The ID that you use to select a timezone with
     TimeZone.getTimeZone refers to a predefined timezone that contains
     daylight savings information (when applicable). For example, the
     following code selects the timezone used in New York, USA.

     // Get the North American Eastern Time definition.
     TimeZone theTz = TimeZone.getTimeZone( "EST" );
     // get a really detailed date format and set it to the right timezone
     DateFormat df = DateFormat.getDateTimeInstance( DateFormat.LONG,
     DateFormat.LONG );
     df.setTimeZone( theTz );
     // create a date in the locale's calendar, set its timezone and hour.
     Calendar day = Calendar.getInstance();
     day.setTimeZone( theTz );
     day.set( 1998, Calendar.FEBRUARY, 1 );
     day.set( Calendar.HOUR, 12 );

     // print that date/time and
     // that date/time 150 full days of milliseconds later.
     System.out.println( df.format( day.getTime() ) );
     System.out.println( df.format(
     new Date( day.getTime().getTime() +    // get the millis
	     150L*24*60*60*1000L ) ) );     // add exactly 150 days of millis

     Results in:

     February 1, 1998 12:00:00 PM EST
     July 1, 1998 1:00:00 PM EDT

     Notice that this example selected something refered to as "EST", but
     that this TimeZone was aware of the daylight savings time change and
     either printed as "EST" or "EDT".

     The confusion is reduced in JDK 1.2, you can use longer TimeZone IDs
     each maps to its own set of text resources. For example the following
     IDs are 5 hour West of GMT and have various DST rules:
     "America/Nassau", "America/Montreal", "America/Havana",
     "America/Port-au-Prince", "America/Grand_Turk", "America/New_York" and
     "EST".

     You can look at a list of other timezone names and offsets in the file
     $JAVAHOME/src/java/util/TimeZone.java

 15. (Sect. 9) How do I create my own Time Zone to apply to dates?

     [*] You can create a TimeZone object with the GMT offset of your
     choice. The following code creates British Time, a timezone that was
     not defined in 1.1.

     britTime = new SimpleTimeZone(0*ONE_HOUR, "Europe/London" /*GMT/BST*/,
	 Calendar.MARCH,  -1, Calendar.SUNDAY /*DOW_IN_DOM*/, 1*ONE_HOUR,
	 Calendar.OCTOBER,-1, Calendar.SUNDAY /*DOW_IN_DOM*/, 1*ONE_HOUR,
     1*ONE_HOUR),

     TimeZone.setDefault( britTime );

     Or you can then apply that TimeZone to a particular Calendar object
     like so:

     Calendar myCal = Calendar.getInstance();
     myCal.setTimeZone( britTime );

     If you are running 1.2, You can choose this existing timezone as the
     default with the code:

     TimeZone.setDefault( TimeZone.getTimeZone( "Europe/London" ) );

     Note that BST is defined from JDK 1.1 and later, but it is Bangladesh
     Standard Time. For a longer example of creating and testing the British
     timezone, Tony Dahlman provides a nice example in his BSumTime.java
     code.

 16. (Sect. 9) How do I create the BST timezone specifically?

     [*] You can create an arbitrary TimeZone object with the code below. In
     most or all other timezones, daylight savings time is handled
     automatically and internally. But GMT is the reference for all other
     timezones, and so does not have the summertime update applied
     automatically. The rules for BST can be found at
     http://www.rog.nmm.ac.uk/leaflets/summer/summer.html

     Here is the code to create a British Summer Time timezone that is
     offset one hour from GMT between two dates:

     import java.util.*;
     import java.text.*;
     // create a BST timezone (code courtesy of Tony Dahlman).

     public static GregorianCalendar setBritSummTime(String zoneName){
	// Set up the default GMT0BST time zone
	SimpleTimeZone bst_tz =
	   new SimpleTimeZone( 0,   // no offset from GMT
	                zoneName,   // individualized tz id
	 // last Sun Mar 1AM
	 Calendar.MARCH,-1,Calendar.SUNDAY,1*60*60*1000,
	 // last Sun Oct 2AM
	 Calendar.OCTOBER,-1,Calendar.SUNDAY,2*60*60*1000
	                );
	SimpleTimeZone.setDefault(bst_tz);

	// Apply TimeZone to create a Calendar object for UK locale
	return (new GregorianCalendar(bst_tz,Locale.UK) );
     }


     and here is how you would print out values using BST:

     // create a template for printing the date
     DateFormat df = DateFormat.getTimeInstance(
	                DateFormat.LONG,Locale.UK);

     // tell the template to use BST tz.
     df.setTimeZone(TimeZone.getDefault());
     System.out.println("Using British Summer Time "
	               +"the time is: "
	               + df.format( BritishSummerTime.getTime() ) );

     // Now get and compare with current time in GMT
     df.setTimeZone(TimeZone.getTimeZone("GMT") );
     System.out.println("\nCurrent time in GMT is: "
	               + df.format(BritishSummerTime.getTime() ) );


     In the winter, this BST zone is aligned with GMT; in the summer it is
     one hour later (4 a.m. GMT is 5 a.m. BST).

     You can look at a list of timezone names and offsets in the file
     $JAVAHOME/src/java/util/TimeZone.java

	        java.util.Calendar and java.util.GregorianCalendar

 17. (Sect. 9)How do I a create a specific date in the Gregorian Calendar?

     [*]If you have a Date use:

     myCal.setTime( myDate );

     If you have a set of integers representing the year, month and day of
     month use:

     Calendar myCal = Calendar.getInstance();
     myCal.set( 1998, Calendar.MARCH, 15 );

     Note: Months start with January = 0!

 18. (Sect. 9) How do I use a GregorianCalendar to extract a few fields from
     a Date?

     [*]The following code shows how to get some fields from a Date.

     Calendar g = Calendar.getInstance();
     g.setTime( aDate );
     int year = g.get( Calendar.YEAR );
     int mon = g.get( Calendar.MONTH );
     int date = g.get( Calendar.DATE );
     mon++;             // in class Calendar & GregCal, months run 0-11 ;-(
     System.out.println( mon + "/" + date + "/" + year);

     If you want to build a string that has a formated date consider using
     SimpleDateFormat.format().

 19. (Sect. 9) Some people use Calendar.getInstance() while others use new
     GregorianCalendar(). Which one is the correct way to get a Calendar?

     [*] Either way is correct, it depends on what you want to be able to
     do. You should use Calendar.getInstance(), if you want your code to be
     ready when the loading of other Calendars are added to the JDK and some
     other calendar is the default for the locale. A particular locale might
     have configured a Hebrew or Islamic Calendar as the default calendar
     and you might want a user to enter a date in his own Calendar, i.e.
     1-Jan-2000 (Gregorian) = 23-Tevet-576 (Hebrew) = 24-Ramadan-1420
     (Islamic). If you really are trying to place a particular Gregorian
     date, i.e. 4-July-1776, into a Date object, you might as well create a
     GregorianCalendar directly.

 20. (Sect. 9) I changed a field using Calendar.set() and then I checked
     another field. Its value is inconsistent with the value I just set.
     What is going on?

     [*]In JDK 1.1.0 the Calendar class did not update all of its fields
     until you called getTime to retrieve the Date that corresponds to the
     fields in the Calendar. To get the earlier version of the Calendar to
     "turn the crank" and calculate all fields you can use the trick:

     myCal.setTime( myCal.getTime() )     // pull the date out and put it back
     in.

 21. (Sect. 9) When I create the date July 4th, 1776 using new
     GregorianCalendar( 1776, 7, 4 ) the month is off by one. What is the
     problem?

     [*]You need to be be aware that months start with January equal to 0. A
     better way to create that date would be:

     independanceDayUSA = new GregorianCalendar( 1776, Calendar.JULY, 4 );

 22. (Sect. 9)Why aren't there constants for milliseconds per day, week or
     year?

     [*]The short answer is: these values are not constants. While some date
     calculations would find these useful, it is important to remember that
     in areas with daylight savings time rules, there are two days per year
     that are not 24 hours long, therefore not all weeks are the same length
     (2 out of 52). Also, because of leap years, not all years are the same
     length.

     If you adding values to a calendar consider using either add or roll;
     for example:

     myCal.add(Calendar.YEAR, 1 );  // get a value 1 year later.

 23. (Sect. 9) By my count the week of the Year is off by one. What is the
     problem?

     [*]The GregorianCalendar class uses the value set by
     setMinimalDaysInFirstWeek() to determine if the fractional week at the
     beginning of the year should be week 1 or week 0. If you don't change
     it, any fractional week could be week 1, depending on the value defined
     for the locale.
 24. (Sect. 9) What timezone does a calendar use when I don't explicitly set
     one?

     [*]The Calendar uses the TimeZone.getDefault() (see discussion under
     TimeZone).

 25. (Sect. 9) Should I stop using Date all together and just use Calendar?

     [*] Probably not. The Calendar class is a much larger than a Date
     object. Many other interfaces in standard APIs are defined using a Date
     object. Use Date objects to hold, store or communicate a date-time
     value. Use a Calendar object to manipulate a date-time value.

 26. (Sect. 9) The GregorianCalendar will not accept a date prior to 4713
     B.C. Why?

     [*]January 1, 4713 B.C. is the "epoch" date for the Julian Day calendar
     which was invented in the 16th century by the Joseph Justus Scaliger.
     "[T]he Julian day calendar, ... does not use individual years at all,
     but a cycle of 7980 astronomical years that counts a day at a time,
     with no fractional days, no mean year, and no leap years. He came up
     with his number by mulitplying three chronological cycles: an 18-year
     solar cycle, a 19-year lunar cycle, and the 15-year indication period
     used by Romans. All three cycles began together at the same moment at
     the start of the "Julian cycle. ... [This] Calendar lives on among
     astronomers."
     -- David Ewing Duncan, "Calendar", Avon Books, 1998; p 207

     Note that the Julian Day calendar is not the same as the Julian
     calendar. The Julian Calendar is named for Julius Caesar. The Julian
     Calendar was used in the Europe from what we now call January 1, 45
     B.C. until at least October 4, 1582 and is still used today by the
     Eastern Orthodox Church to date holidays.

     The limitation on dates prior to 4713 BC has been dropped in JDK 1.2.

 27. (Sect. 9) The Calendar class is said not to handle certain historical
     changes. Can you explain some of the limitations?

     [*]The date of change from the Julian to the Gregorian calendar depends
     on where you lived at the time. The date can vary from 1582 (most
     Catholic countries, which of course followed the Papal edict) to 1949
     (China). The date of the cutover from using the Julian Calendar (leap
     years ever 4 years) to using the Gregorian Calendar (every 4 years,
     except every 100 unless divisable by 400) is controlled by the method
     GregorianCalendar.setGregorianChange(Date).

     It is also the case that January 1 was not always the beginning of the
     year. January 1 was standardized by Julius Caesar in 45 B.C. and Pope
     Gregory XIII in 1582, but others who used the Julian Calendar between
     those dates used other dates for New Years Day. (Anyone who has ever
     been involved in a standardization effort may find it interesting that
     neither an emperor nor a pope could actually complete the
     standardization effort).

     The Calendar class uses a TimeZone which does not handle historical
     changes, i.e. the SimpleTimeZone contains only two dates the "spring
     forward" and "fall back" dates and a date that the DST starts (see
     SimpleTimeZone.setStartYear() ). If the local definitions have changed
     then a date/time may not accurately reflect the historical local time.

     As noted above, the Date object does not usually include leap seconds,
     unless your hardware includes leap seconds.

     While the Calendar class is more than useful for international
     business, it may not be what you want for doing UTC timebased
     calculations or historical dates and times without a more careful
     analysis of its design limits.

	       java.text.DateFormat and java.text.SimpleDateFormat

 28. (Sect. 9) How do I convert a date in one format to another?

     [*] The following code illustrates the technique:

     import java.text.*;
     public class DateTest {
       public static void main( String[] args ) {
	 SimpleDateFormat df1 =
	   new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.S");
	 SimpleDateFormat df2 =
	   new SimpleDateFormat("dd-MMM-yy");
	 String startdatetime = "1998-09-09 06:51:27.0";

	 try {
	   System.out.println("Date is " +
	     df2.format( df1.parse(startdatetime) ));
	 } catch (ParseException pe) {
	   System.out.println("ParseException " + pe );
	 }
       }
     }

     When run, the program outputs "Date is 09-Sep-98"
 29. (Sect. 9) How do I use DateFormat to parse a string containing a date?

     [*] The easiest way to parse a date that is in a known format is to use
     SimpleDateFormat.parse().

     DateFormat df = new SimpleDateFormat( "HH:mm" );
     df.setTimeZone( TimeZone.getDefault() ); // if using JDK 1.1 libraries.
     df.setLenient( false );                  // to not allow 26:65 etc.
     Date lateLunchOnDayZero = df.parse( "12:30" );
     System.out.println( lateLunchOnDayZero );

     The above code would result in (when in the MST timezone).

     Thu Jan 01 12:30:00 MST 1970

     To parse other date and time fields, refer to the SimpleDateFormat
     documentation.

 30. (Sect. 9) How do I use a DateFormat to create a text string from a
     Date?

     [*] The easiest way to create a string from a date is to use a
     SimpleDateFormat.format(). The following code illustrates how this can
     be done.

     DateFormat df = new SimpleDateFormat( "yyyy.MMM.dd HH:mm:ss.SSS z" );
     df.setTimeZone( TimeZone.getDefault() ); // JDK 1.1
     System.out.println( df.format( d ) );    // where d is a Date

     For other possible fields from the calendar, see the document for
     SimpleDateFormat.

 31. (Sect. 9) What timezone does a SimpleDateFormat use when I don't
     specify one?

     [*]In JDK 1.1, the SimpleDateFormat uses the first timezone defined for
     the locale. In JDK 1.2, it uses the default timezone. See the
     discussion above on how this differs from the Calendar class).

 32. (Sect. 9) I'm not yet using JDK 1.2 and I don't want the DateFormat to
     use the 1st timezone for the locale. How do I change the timezone in a
     SimpleDateFormat to use a different timezone?

     [*] The following code sets the timezone of a DateFormat to the current
     default.

     DateFormat df = DateFormat.getDateInstance();
     df.setTimeZone(TimeZone.getDefault());

     or to set it to a timezone of your chioce.

     df.setTimeZone(TimeZone.getTimeZone( "MST" ) ) // Mtn Time, Denver USA

 33. (Sect. 9) What century is assumed when I use a two digit year in a
     SimpleDateFormat string?

     [*]In JDK 1.1, the default start for the century used by
     SimpleDateFormat for 2 digit years is 80 years before the current date.

     This means that in 1998: 1 = 2001, 2 = 2002, ... 17 = 2017, 18 = 2018,
     19 = 1919, 20 = 1920, ... 98 = 1998, 99 = 1999,

     In JDK 1.2 you can change this "default century start date" with the
     method set2DigitYearStart( Date) and get its current value
     with the method get2DigitYearStart(). One thing to note is that since
     set2DigitYearStart takes a date not a year, you can have your default
     century begin at any day or hour.

     When running under JDK 1.1, it is probably best to avoid two-digit year
     fields, when the dates entered could possibly fall outside of the range
     -- now less 80 years and now plus 20 years. If you want to allow
     two-digit year fields in JDK 1.2 and beyond, consider setting the
     2DigitYearStart property to something appropriate,  For example, set it
     to today, when all dates to be entered are in the future (i.e. an
     expiration date), or set it to today less 100 years, when the value is
     always in the past (i.e. birthdate, death date).

 34. (Sect. 9) Does the above mentioned limitation of 2 digit years in JDK
     1.1 mean that java.text.SimpleDateFormat is not Y2K compliant?

     [*] No. It means that any code you write that (1) allows the entry of 2
     digit years and (2) does not make sure they are in an appropriate
     century, would not pass a careful Y2K analysis. This code was put here
     so you could sensibly read old files with non-Y2K compliant dates, not
     so you could create new ones. Once you are using JDK 1.2 it is better
     to set the 2DigitYearStart property to something appropriate for any
     two-digit year field which you are parsing.

	               java.sql.Date and java.sql.TimeStamp

 35. (Sect. 9) What timezone does a java.sql.date use when converting to an
     SQL DATE?

     [*]This is another hidden use of the default java.util.TimeZone. If you
     have carefully set every timezone in every Calendar and DateFormat you
     are using, but you don't set the default in java.util.TimeZone when a
     java.util.Date is converted to a java.sql.Date you may not end up with
     the value you expected in your database.

 36. (Sect. 9) When I print a jave.sql.Timestamp it doesn't include any
     milliseconds. What is the problem?

     [*] If you print the java.sql.Timestamp directly you will see this
     problem. The following code demonstrates this surprising behavior.

     // incorrect use of java.sql.Timestamp
     DateFormat df = new SimpleDateFormat( "MM/dd/yy hh:mm:ss.SSS a" );
     df.setTimeZone( TimeZone.getDefault() );    // needed in JDK 1.1

     java.sql.Timestamp t = new java.sql.Timestamp( 94, Calendar.JANUARY, 1,
	     13, 45, 59, 987654321 );
     System.out.println( df.format( t ) ) ; // Wrong! no fractions of a second.

     The results of the above code are:

     01/01/94 01:45:59.000 PM

     The above code is using whatever is in the super class (java.util.Date)
     and assumes all of those parts are filled in. java.sql.Timestamp could
     have stored the whole milliseconds in the millisecond part of a
     java.util.Date, and stored the nanoseconds that are not whole
     milliseconds in an additional field. They chose to ignore the fractions
     of a second in the java.util.Date and put all fractional parts in an
     additional nanosecond field.

     The following code shows how to convert a java.sql.timestamp to a
     java.util.Date.

     Date d = new Date(t.getTime() + (t.getNanos() / 1000000 ));
     // 1 Milli = 1x10^6 Nanos
     System.out.println( df.format( d ) ) ; // Right! At least we have the millis

     The result of the above code is a better approximation of the timestamp
     value:

     01/01/94 01:45:59.987 PM

	               -------------------------------

10. AWT

	                  Text, Textfield, and TextArea

  1. (Sect. 10) How can I write text at an angle?

     [*] Check out http://www.nyx.net/~jbuzbee/font.html. Jim has some code
     to do exactly this. A good way to do it is to draw the text to an
     offscreen image and write an ImageFilter to rotate the image.

     Also, from JDK 1.2 on, the Java 2D API handles arbitrary shapes, text,
     and images and allows all of these to be rotated, scaled, skewed, and
     otherwise transformed in a uniform manner. A code example would be:

     import java.awt.*;
     import java.awt.geom.*;
     public class r extends Frame {

	 public static void main(String args[]) { new r(); }

	 r() { setSize(200,200); setVisible(true); }

	 public void paint(Graphics g) {
	     Graphics2D g2D = (Graphics2D) g;
	     AffineTransform aft = new AffineTransform();
	     aft.setToTranslation(100.0, 100.0);
	     g2D.transform(aft);
	     aft.setToRotation(Math.PI / 8.0);
	     String s = "Rotated Hello World";

	     for (int i = 0; i < 16; i++) {
	         g2D.drawString(s, 0.0f, 0.0f);
	         g2D.transform(aft);
	     }
	 }
     }

     There is more info about the 2D API at
     http://java.sun.com/products/java-media/2D/index.html and
     http://developer.javasoft.com/developer/technicalArticles/

  2. (Sect. 10) How do you change the font type and size of text in a
     TextArea?

     [*] Like this.

     myTextArea.setFont(new Font("NAME",