From: elharo@sunsite.unc.edu Newsgroups: comp.lang.java.programmer,comp.lang.java.api,comp.lang.java.misc,comp.lang.java.tech,alt.www.hotjava Organization: Cafe Au Lait Followup-To: poster Subject: comp.lang.java FAQ Archive-name: computer-lang/java-faq/part1 Posting-Frequency: weekly Last-modified: 1996/12/14 Version: 1.3 URL: http://sunsite.unc.edu/javafaq/javafaq.html
This document is Copyright 1995, 1996 by Elliotte Rusty Harold. For information about reproduction, redistribution and other such rights please see the end of this file.
int
to an Integer
?
a float
to a Float
?
for
loops have the same syntax in all four languages);
but it is not based on any of those languages, nor have efforts
been made to make it compatible with them.Java is sometimes referred to as C++ ++ --. The language was originally created because C++ proved inadequate for certain tasks. Since the designers were not burdened with compatibility with existing languages, they were able to learn from the experience and mistakes of previous object-oriented languages. They added a few things C++ doesn't have like garbage collection and multithreading; and they threw away C++ features that had proven to be better in theory than in practice like multiple inheritance and operator overloading. (There's still argument over whether they made the right choices. I tend to think they were correct to throw out operator overloading and probably correct to throw out multiple inheritance. For now let's just say that neither choice is likely to be reviewed soon.)
Even more importantly Java was designed from the ground up to allow for secure execution of code across a network, even when the source of that code was untrusted and possibly malicious. This required the elimination of more features of C and C++. Most notably there are no pointers in Java. Java programs cannot (at least in theory) access arbitrary addresses in memory.
Furthermore Java was designed not only to be cross-platform in source form like C, but also in compiled binary form. Since this is frankly impossible across processor architectures, Java is compiled to an intermediate byte-code which is interpreted on the fly by the Java interpreter. Thus to port Java programs to a new platform all that is needed is a port of the interpreter and a few native code libraries.
Finally Java was designed to make it a lot easier to write bugfree code. Shipping C code has, on average, one bug per 55 lines of code. About half of these bugs are related to memory allocation and deallocation. Thus Java has a number of features to make bugs less common:
In 1989 Joy sold his Sun stock, invested heavily in Microsoft and moved out of mainstream Sun to Aspen, Colorado. By the early 90's Bill was getting tired of huge programs. He decided that he wanted to be able to write a 10,000 line program that made a difference. In late 1990 Bill wrote a paper called Further which outlined his pitch to Sun engineers that they should produce an object environment based on C++. Today Joy freely admits that C++ was too complicated and wasn't up to the job.
Around this time James Gosling (of emacs fame) had been working for several months on an SGML editor called "Imagination" using C++. The Oak language (now Java) grew out of Gosling's frustration with C++ on his "Imagination" project.
Patrick Naughton, then of Sun, now vice-president of technology at StarWave, started the Green Project on December 5th, 1990. Naughton defined the project as an effort to "do fewer things better". That December he recruited Gosling and Mike Sheridan to help start the project. Joy showed them his Further paper, and work began on graphics and user interface issues for several months in C.
In April of 1991 the Green Project (Naughton, Gosling and Sheridan) settled on smart consumer electronics as the delivery platform, and Gosling started working in earnest on Oak. Gosling wrote the original compiler in C; and Naughton, Gosling and Sheridan wrote the runtime-interpreter, also in C. (The Green project never wrote a single line of C++.) Oak was running its first programs in August of 1991. Joy got his first demos of the system that winter, when Gosling and Naugton went skiing at Joy's place in Aspen.
By the fall of 1992 "*7", a cross between a PDA and a remote control, was ready This was demoed to Scott McNealy, Sun's president, in October. He was blown away. Following that the Green Project was set up as First Person Inc., a wholly owned Sun subsidiary.
In early 1993 the Green team heard about a Time-Warner request for proposal for a settop box operating system. First Person quickly shifted focus from smart consumer electronics (which was proving to be more hype than reality) to the set-top box OS market, and placed a bid with Time-Warner.
Fortuitously, Sun lost the bid. The Time-Warner project went nowhere, the same place it probably would have gone if Sun had won the bid. First Person continued work on settop boxes until early 1994, when it concluded that like smart consumer electronics settop boxes were more hype than reality.
Without a market to be seen First Person was rolled back into Sun in 1994. However around this time it was realized that the requirements for smart consumer electronics and settop box software (small, platform independent secure reliable code) were the same requirements for the nascent web.
For a third time the project was redirected, this time at the web. A prototype browser called WebRunner was written by Patrick Naughton in one weekend of inspired hacking. After additional work by Naughton and Jonathan Payne this browser became HotJava. The rest, as they say, is history.
Information in this section is primarily based on the first hand accounts of Bill Joy and Patrick Naughton (which don't always agree). No doubt other people have still different memories of what occurred. If you've got any more first hand information about what went on in the Green project I'd like to hear from you.
At the lowest level the advantage of Java to the web is that it provides a secure, cross-platform way for code to be executed. At a somewhat higher level Java adds several features to existing web sites:
An IRIX port has mostly been completed by Simon Leinen. SGI's own port is available at http://www.sgi.com/Products/cosmo/cosmo_instructions.html
A Linux port is in fairly good shape. See http://java.blackdown.org/java-linux.html.
IBM has ported Java to Windows 3.1, OS/2, and AIX. It is working on ports for MVS and OS/400. See http://ncc.hursley.ibm.com/javainfo/hurindex.html .
The OSF has ported Java to Unixware, the Bull Estrella or other PowerPC running AIX4.1, X86 running DASCOM OSF/1 , the Digital Alpha running Digital UNIX 3.2 , the HP700 series running HPUX 10.x, the NCR Globalyst (Pentium) running UNIX SysV, and Sony NEWS (MIPS) running Sony NEWS 6.1.1. See http://www.osf.org/mall/web/JDK/.
Other ports are underway for Nextstep, SunOS 4.1, the Amiga and possibly other platforms.
In the past new versions of Java have most often been made available first for Solaris. If you have to have the latest version as soon as it's released, or if you're developing "Bet your company" applications with Java, you should probably be running Solaris on a SparcStation. Otherwise, if you just want to learn the language, you can get away with an Intel based Windows 95 or NT machine with a lot of RAM.
Netscape 2.0 and later plays Java applets on Windows NT, Windows 95, Solaris, SunOS 4.1, Linux and most other Unix platforms. Netscape 3.0 for the Mac also supports Java. You can compile Java programs on these platforms with Netscape. First download the classes.zip file from the Solaris distribution of the JDK. (You have to download the entire JDK. You can't get just the classes.zip file.) Next set your CLASSPATH environment variable to include the classes.zip file. For example, on Unix, if you put the file in /usr/local/lib/classes.zip, then you would set it like this:
sh: % CLASSPATH=$CLASSPATH:/usr/local/lib/classes.zip csh: % setenv CLASSPATH "$CLASSPATH:/usr/local/lib/classes.zip"You'll probably want to put this line in your .login or .cshrc file. Of course you'll need to adjust this to match where you've installed these files and to add any other classes you use. Finally you compile programs from the command line like this:
% netscape -java sun.tools.javac.Main HelloWorld.javaYou can always alias netscape -java sun.tools.javac.Main to just javac to make this more transparent.
You can also run command-line programs that don't use the AWT in the same way, like this:
% netscape -java HelloWorld.classYou can't use netscape -java to run programs that use the AWT, but you can of course play applets in Netscape..
A little further out in left field, it isn't even necessary to know Java to write Java programs. Intermetrics is beta testing an ADA-95 to Java byte code compiler. Other such cross-compilers are probably possible including ANSI Fortran-77. However the one most people probably want, that is a C/C++ to Java byte code compiler, is probably not possible due to Java's lack of pointers.
Where does Javascript fit in?
To quote from p. 31 of the first edition of my book, The Java Developer's Resource,
Java and JavaScript are about as closely related as the Trump Taj Mahal in Atlantic City is to the Taj Mahal in India. In other words Java and JavaScript both have the word Java in their names. JavaScript is a programming language from Netscape which is incorporated in their browsers. It is superficially similar to Java in the same way C is similar to Java but differs in all important respects.
More generally and less technically an application is a stand-alone program, normally launched from the command line, and which has more or less unrestricted access to the host system. An applet is a program which is run in the context of an applet viewer or web browser, and which has strictly limited access to the host system. For instance an applet can normally not read or write files on the host system whereas an application normally can.
The actions of both applets and applications, however, can be controlled by SecurityManager objects. If you can change the SecurityManager that's used you can change what an applet or an application is and is not allowed to do. Thus these are not hard and fast differences, though this is normally how they separate out in practice.
For many more web sites see the Cafe Au Lait links page at http://sunsite.unc.edu/javafaq/links.html.
The second book I recommend is
Java in a Nutshell: A Desktop Quick Reference for Java
Programmers
by
For people with no prior experience in programming I recommend Kris Jamsa's Java Now!, ISBN: 1-884133-30-4, $16.95, Jamsa Press.
Finally The Java Handbook
by
For details about these and many more books see the Cafe Au Lait books page at http://sunsite.unc.edu/javafaq/books.html
int
) Java specifies
everything.
Here are the detailed data types:
boolean
true
and false
only.
true
and false
are defined constants of the language
and are not the same as True
and False
,
TRUE
and FALSE
, zero and nonzero, 1 and 0
or any other numeric value. Booleans may not be cast into any other
type of variable nor may any other variable be cast into a boolean.
byte
short
int
long
float
Like all numeric types floats may be cast into other numeric types (byte
,
short
, long
, int
, double
).
When lossy casts to integer types are done (e.g.
float
to short
) the fractional part is truncated and the
conversion is done modulo the length of the smaller type.
double
char
Chars are not the same as bytes, ints, shorts or Strings.
sizeof
isn't necessary in Java because all sizes are precisely
defined. i.e. an int
is always 4 bytes.
This may not seem to be adequate when dealing with objects that
aren't base data types. However even if you did know the size of
a particular object, you couldn't do anything with it anyway.
You cannot convert an arbitrary object into bytes
and back again.
if
, else
, for
,
while
, do while
and switch
statements. The syntax is identical to C's.
However all condition tests must return boolean values. Since
non-boolean assignment statements
and arithmetic statements do not return a boolean value,
some of the more obfuscated condition tests in C are prohibited.
argv
has become a string array commonly called args
and
args[0]
is the first command line argument, not the
name of the program. The other arguments are all shifted one to the
left from where they'd be in C or C++.
/* This is a comment */
comment
from C and the // This is a C++ comment
However comments that begin with a /**
are special.
These comments should only be used before
a method or class declaration. They indicate that the comment should be included in
automatically generated documentation for that declaration.
Superclasses of a class are indicated with the extends
keyword rather than with a :
.
Methods must be defined inside the class to which they belong. They may not be declared inside the class and defined outside the class as is common in C++.
Features removed that make Java easier to read and understand than
C++ include #define
, typedef
, operator
overloading, enum
, unions and structs.
The main feature removed to make Java safer and more robust than C++ is pointer arithmetic.
Other features removed include global variables, standalone functions (everything is a method), friend functions (Everything in a package is a friend of everything else in the package.) and non-virtual functions.
A number of features have been added to Java to make it safer including true arrays with bounds checking, garbage collection, concurrency, interfaces (from Objective C) and packages. There is no need to explicitly allocate or free memory in Java.
Long answer: Object variables in Java are all references. A reference acts like a pointer in most other languages. (Though they're handles, not pointers, in most Java implementations. The notable exception is Microsoft's.) The main difference is that you can't do pointer arithmetic on references. Therefore wherever you'd use a pointer to an object in C++, in Java you should just use the object itself.
On the other hand the primitive data types (int, float,
double, char, byte, short, long
and boolean
) are
not references. If you want to get a reference to one of these you
need to wrap it in a class first. Java provides ready-made
type-wrapper classes in the java.lang package for Boolean
,
Character
, Integer
, Double
,
Float
, and Long
. Bytes and shorts can be
stored in the Integer class as well. Java 1.1 will add Byte
,
Short
, and Void
classes
too.
scanf
, fscanf
and sscanf
functions.
Roughly equivalent functionality is scattered across several classes though.
You first read an input line into a string
using DataInputStream.readline()
.
Next use the
StringTokenizer
class in java.util
to split the String
into tokens.
By default StringTokenizer
splits on white space (spaces,tabs, carriage returns and newlines),
but that is user definable.
import java.util.StringTokenizer;
class STTest {
public static void main(String args[]) {
String s = "9 23 45.4 56.7";
StringTokenizer st = new StringTokenizer(s);
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
}
}
prints the following output:
9 23 45.4 56.7Finally you convert these tokens into numbers using the type wrapper classes as described in the next question.
Integer
, Float
,
Double
and Long
type wrapper classes as indicated by the following code snippet:
class ConvertTest {
public static void main (String args[]) {
String str;
str = "25";
int i = Integer.valueOf(str).intValue();
System.out.println(i);
long l = Long.valueOf(str).longValue();
System.out.println(l);
str = "25.6";
float f = Float.valueOf(str).floatValue();
System.out.println(f);
double d = Double.valueOf(str).doubleValue();
System.out.println(d);
}
}
There are no equivalent Short
and Byte
classes
in Java 1.0. These will be added to Java 1.1.
For shorts and bytes use the Integer
class
but use the byteValue()
or shortValue()
methods instead.
system()
call (or your OS's equivalent) to execute the java
interpreter with appropriate command line arguments.Several people have written to me with apparently different methods that involve deep, dark hacks to the java interpreter, dump and undump and other tricks. However so far I don't understand any of this.
In Java 1.1 a serialization interface will be added to the language. It is currently in beta.
An applet can also get references to all other applets on the same
page using the getApplets()
method of java.applet.AppletContext
. Once
you've got a reference to an applet,
you can commuincate with it by
using its public members.
It is conceivable to have applets in different virtual machines that talk to a server somewhere on the Internet and store any data that needs to be serialized there. Then, when another applet needs this data, it could connect to this same server. Implementing this is non-trivial.
A number of organizations have developed special http servers that allow applets or other clients to run Java programs on the server in a secure environment. Most notably Sun's Jeeves implements a servlet interface for this purpose. The W3C's JigSaw implements a similar idea called resource objects.
For example suppose you're writing an inventory database. The inventory may include many different items of many different types and classes. However each item in the warehouse needs to be able to tell you its price. Normally you would implement this by having each class extend a common superclass. However that's not always convenient. Instead you can declare an interface called Price with a price() method like this:
public interface Price {
public float price();
}
Any class which implements the Price
interface must contain a method with the signature
public float price()
. The code of the price()
method is included separately in each
separate class which implements Price
, not in the Price
interface itself.Different classes in your warehouse can each implement the Price interface like this:
public class Monopoly extends BoardGame implements Price {
// other methods
public float price() {
return 14.95;
}
}
When other code is passed an object, it can test whether the object implements Price with the
instanceof operator. For example,
if (o instanceof Price) System.out.println("Subtotal is " + o.price());
In fact, interfaces can be used to tag objects. The java.rmi.Remote interface declares no methods. Its sole purpose is to indicate that an object is a remote object. In general, sub-interfaces of java.rmi.Remote will declare remote methods, however. For example,
public interface Hello extends java.rmi.Remote {
public String sayHello();
}
public class HelloImpl extends UnicastRemoteServer implements Hello {
public String sayHello() {
return "Hello";
}
}
For more information about the java.rmi package, see
http://chatsubo.javasoft.com/current/rmi/index.html
or Chapter 14 of my book, Network Programming in Java, from O'Reilly & Associates
(available early 1997).
An abstract class cannot be instantiated. Only its subclasses can be instantiated.
Extensions are planned for the class library though. In particular Sun is working on extensions for 3D, multimedia, telephony, improved graphics and multicasting.
int
to an Integer
?
a float
to a Float
?int
or float
to an
Object such as an Integer
or a Float
.
However the proper way to do this isn't very
hard. Instead do
int x = 5;
myInteger = new Integer(x);
print()
.
Note that some of the classes like DataOutputStream have unoverloaded
methods like writeInt()
and writeByte()
.
Java does have references. A reference is an abstract identifier for an object. It is not a pointer. A reference tags a particular object with a name in the Java virtual machine so that the programmer may refer to it. How exactly the virtual machine implements references at the level of machine code is VM-dependent and completely hidden from the programmer in any case. Most VMs including Sun's use handles, not pointers. A handle is a pointer to a pointer. At the level of machine code in the CPU a reference is an address in memory where the address of the object is stored. This way the objects can be moved around in memory and only the master pointer needs to be updated rather than all references to the object. This is completely hidden from the Java programmer, though. Only the implementer of the virtual machine needs to worry about it. Indeed, this is not the only way references can be implemented. Microsoft's VM actually does use pointers rather than handles. Other schemes are possible.
import java.awt.Point;
class changePoint {
public static void main(String args[]) {
Point p1 = new Point(0, 0);
changePoint(p1);
System.out.println(p1);
}
static void changePoint(Point p) {
p.x = 38;
p.y = 97;
}
}
It prints:
java.awt.Point[x=38,y=97]Therefore the point has been changed. However the reference, which is what was really passed, has not been changed. To see that consider the following program.
import java.awt.Point;
class dontChangePoint {
public static void main(String args[]) {
Point p1 = new Point(0, 0);
dontChangePoint(p1);
System.out.println(p1);
}
static void dontChangePoint(Point p) {
p = new Point(38, 97);
}
}
It prints:
java.awt.Point[x=0,y=0]What happened in this example was that a copy of the reference
p1
was passed to the dontChangePoint()
method. A new Point
object was
then assigned to that copy. However this did not change the old
reference in the main method. In the previous example the reference
p
in the changePoint()
method and p1
in
the main()
method both referred
to the same object. In this example p
and p1
refer to different
objects after the new Point
is assigned to p
.
final
class can no longer be subclassed. Mostly this is done for
security reasons with basic classes like String
and Integer
.
It also allows the compiler to make some optimizations,
and makes thread safety a little easier to achieve.
Methods and variables may be declared final
as well. This means they
may not be overridden in a subclass.
It's also possible to make a static
field final
to get the effect
of C++'s const
statement or some uses of C's #define
, e.g.
public static final int myVar = 0;
Static
variables and methods are instantiated only once per class.
In other words they are class variables, not instance
variables. If you change the value of a static
variable in a
particular object, the value of that variable changes for all
instances of that class.
Static methods can be referenced with the name of the class rather
than the name of a particular object of the class (though that works
too). That's how library methods like
System.out.println()
work.
PERFORM
or BECOME
in Java 1.0. These would probably open
security holes. There are workarounds for some things you might want
to do using interfaces. In Java 1.1 the Core
Reflection API will provide most of the functionality you need.
However this API will likely not be available to applets and
servlets due to security issues.
When the user clicks the mouse, types on the keyboard, drags and drops, or does any of a few other things, the operating system produces an event. This event is passed to Java, and the Java runtime tries to figure out which component the event was intended for.
The Java runtime then passes that event to the
handleEvent(Event e)
method of some Component
. The
Component
's handleEvent()
method contains a big if-else statement to
look at the type of event and respond appropriately. What the
handleEvent()
method does depends on the type of Component. Generally
some events are ignored and other events are passed to methods that
know how to respond to those events. For instance a MOUSE_DOWN event
is passed to mouseDown(). The table below shows the events the
default handleEvent()
can deal with. When one of these events
occurs, handleEvent()
passes it and various other information to the
specified method.
Event Method Called -------------------------------------------------------- Event.MOUSE_ENTER: mouseEnter(evt, evt.x, evt.y) Event.MOUSE_EXIT: mouseExit(evt, evt.x, evt.y) Event.MOUSE_MOVE: mouseMove(evt, evt.x, evt.y) Event.MOUSE_DOWN: mouseDown(evt, evt.x, evt.y) Event.MOUSE_DRAG: mouseDrag(evt, evt.x, evt.y) Event.MOUSE_UP: mouseUp(evt, evt.x, evt.y) Event.KEY_PRESS: keyDown(evt, evt.key) Event.KEY_ACTION: keyDown(evt, evt.key) Event.KEY_RELEASE: keyUp(evt, evt.key) Event.KEY_ACTION_RELEASE: keyUp(evt, evt.key) Event.ACTION_EVENT: action(evt, evt.arg) Event.GOT_FOCUS: gotFocus(evt, evt.arg) Event.LOST_FOCUS: lostFocus(evt, evt.arg)By default each of these methods does nothing. Furthermore, by default all other events do nothing. If you want to do something when one of the above evnts occurs in your component, subclass the component and override the appropriate method. For example, to create a Canvas that prints the message "Don't Tread on Me!" every time the user clicks on it, use the following subclass of Button:
public class noTread extends Canvas {
public boolean mouseDown(Event e, int x, int y) {
System.out.println("Don't Tread on Me!");
return true;
}
}
Button
, Choice
, TextField
, and Checkbox
are special because of how
they're implemented as native widgets. They do not see MOUSE_DOWN
,
MOUSE_UP
, KEY_PRESS
, and other such events. Rather they receive one
event and one event only: Event.ACTION_EVENT
. When a Button
is
pressed, the user hits return in a TextField
, the user double clicks on a List
item,
clicks a Checkbox
, or
selects from a Choice
, an ACTION_EVENT
is generated. If you haven't
overridden handleEvent()
, this is passed to the action()
method of the
component's container. These four components are the only things
which generate ACTION_EVENT
s. No other component will generate an
ACTION_EVENT
.
Each event handler method, including handleEvent()
, returns true
if
the event was completely handled and false
if it was not. If false
is returned, then the event is passed to the component's container
to see if the container want's to process the event.
If you want to respond to a different set of events, you must
override handleEvent()
. You can either completely replace it or just
add the extra events you want to handle and then return
super.handleEvent()
for other types of events. For example to print
all the events as they happen in your applet you might use this
handleEvent()
method:
public boolean handleEvent(Event e, int x, int y) {
System.out.println(e);
return super.handleEvent(e, int x, int y);
}
mouseDown, mouseUp, keyDown, and all the other event methods would
still be called by the superclass. If you don't handle an event in
the handleEvent()
method, return super.handleEvent(e)
to give your
superclass an opportunity to process the event. In this case, we've
handled the event but not completely so we still let the superclass
process it by returning super.handleEvent(e, int x, int y)
.
The return value of handleEvent()
is important. If handleEvent()
returns
true, that means the event has been fully digested and no further
processing is needed. On the other hand if handleEvent()
returns
false, then the event is passed to the component's container to be
handled.
Note that this all works for any component at all. You'll most commonly override these methods in a subclass of Applet or perhaps Frame. However the same methods and techniques apply to all subclasses of Component.
The API documentation confuses the issue because of the ambigious use of the word parent. In object-oriented circles the word parent usually refers to the superclass. However in the context of the AWT, the word parent refers to the container that contains a component. Thus in the statement:
returnthe word parent means the component's container, not its superclass.true
if the event has been handled and no further action is necessary;false
if the event is to be given to the component's parent
You must distinguish between the container/component
hieararchy and the inheritance hierarchy. By default, the way an event
travels has nothing to do with the inheritance
hieararchy. If you override an event handling method, then events
passed to that method will not be passed to a component's superclass unless
you specifically ask them to be. However, in most cases your handleEvent()
method will return super.handleEvent()
to give the superclass a crack at
handling the event rather than simply returning false.
To sum up, when you write a subclass of Component
, you can either
respond to specific events by overriding the methods that correspond
to those events, such as mouseDown()
; or you can respond to all
events by overriding handleEvent()
. Each of your event handling
methods must return a boolean
. Return true
when an event has been
completely processed, and return false
when you want the component's
container to try to handle the event. When overriding handleEvent()
,
you also have an option to return super.handleEvent()
to ask the
superclass to handle the event and decide whether or not to pass it
along to the component's container.
Instead if you need to do clipping, create separate offscreen Images for each clipping region. Each Image should be the size of the clipping region you desire. Draw into those offScreen Images, and then copy them onto the appropriate section of the of your applet window using java.awt.Graphics.drawImage(). Some coordinate conversion will almost certainly be necessary.
If the background image isn't a simple color then you'll first need to copy the appropriate part of that image to your offscreen clipping Image. You can do this by drawing your background Image into your offscreen region with Graphics.drawImage and a suitable shifting of coordinates.
This all works for rectangular regions only since all Images are rectangular. More complicated geometries can be faked if all but one section contains only simple colors.
FileInputStream(String)
constructor and use one of
the various read()
methods to read the data into an array of
bytes. For example the following program reads raw data
from a file specified on the command line. It then writes
the same data to the standard output.
import java.io.*;
class ReadRawData {
public static void main (String args[]) {
boolean done = false;
byte b[] = new byte[1024];
int num_bytes = 0;
FileInputStream fin = null;
try {
fin = new FileInputStream(args[0]);
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("You have to give me the name of a file to open.");
System.exit(0);
}
catch (FileNotFoundException e) {
System.out.println("Could not open input file " + args[0]);
System.exit(0);
}
catch(IOException e) {
System.out.println("Error while opening input file" + args[0]);
System.exit(0);
}
catch (Exception e) {
System.out.println("Unexpected exception: " + e);
System.exit(0);
}
try {
num_bytes = fin.read(b);
}
catch(IOException e) {
System.out.println("Finished Reading: " + e);
done = true;
}
catch (Exception e) {
System.out.println("Unexpected exception: " + e);
System.exit(0);
}
while(!done) {
System.out.write(b, 0, num_bytes);
try {
num_bytes = fin.read(b);
}
catch(IOException e) {
System.out.println("Finished Reading: " + e);
done = true;
}
catch (Exception e) {
System.out.println("Unexpected exception: " + e);
System.exit(0);
}
if (num_bytes == -1) done = true;
} // end while
} // end main
} // end ReadRawData
On the other hand if you're reading a text file you'll
probably want to use a DataInputStream which gives you a
readLine() method that returns successive lines of the file
as Java Strings. You can then process each String as you
see fit.
// Implement the Unix cat utility in java
import java.io.*;
class cat {
public static void main (String args[]) {
String thisLine;
//Loop across the arguments
for (int i=0; i < args.length; i++) {
//Open the file for reading
try {
FileInputStream fin = new FileInputStream(args[i]);
// now turn the FileInputStream into a TextFileStream
try {
DataInputStream myInput = new DataInputStream(fin);
try {
while ((thisLine = myInput.readLine()) != null) { // while loop begins here
System.out.println(thisLine);
} // while loop ends here
}
catch (Exception e) {
System.out.println("Error: " + e);
}
} // end try
catch (Exception e) {
System.out.println("Error: " + e);
}
} // end try
catch (Exception e) {
System.out.println("failed to open file " + args[i]);
System.out.println("Error: " + e);
}
} // for ends here
} // main ends here
}
This code emulates the Unix "cat" command. Given
a series of filenames on the command line it concatenates
the files onto the standard output. Since this program
didn't work the first few times I wrote it, I even tossed in
some error checking and exception handling via try and
catch.See the Java class API documents for details of the syntax for these methods.
Within an application, however, file access is straight-forward. There are several ways but here is a simple example using formatted output streams:
import java.io.*;
class PrintToAFile {
public static void main (String args[]) {
//First open the file you want to write into
try {
FileOutputStream fout = new FileOutputStream("test.out");
// now convert the FileOutputStream into a PrintStream
PrintStream myOutput = new PrintStream(fout);
// Now you're able to use println statements just as if you were using System.out.println
// to write to the terminal
myOutput.println("Hello There!");
myOutput.println(1 + " + " + 1 + " = " + (1+1));
}
catch (IOException e) {
System.out.println("Error opening file: " + e);
System.exit(1);
}
} // main ends here
}
There are a number of other things to note about writing
data to a file. This program creates or opens a file called
"test.out" in the same directory as the running
program. However you could pass it a full pathname to a
file in a different directory instead.
You should also learn about DataOutputStreams and the
write()
method when you get a chance.
DataOutputStreams and DataInputStreams are used for moving
data between Java programs in a portable way. The various
incarnations of the write() method are used for writing and
reading arbitrary byte streams. What we've demonstrated here
is more suitable for human consumption.
raf.seek(raf.length())
. The following example
demonstrates by appending the string "Kilroy was here!" to every
file specified on the command line.
import java.io.*;
class AppendToAFile {
public static void main (String args[]) {
for (int i = 0; i < args.length; i++) {
//First open the file you want to append to
try {
RandomAccessFile raf = new RandomAccessFile(args[i], "rw");
// Position yourself at the end of the file
raf.seek(raf.length());
// Write the String into the file. Note that you must
// explicitly handle line breaks.
raf.writeBytes("\nKilroy was here!\n");
}
catch (IOException e) {
System.out.println("Error opening file: " + e);
}
}
}
}
The first thing to know is that there are two ways a CGI program can accept data from a web browser, GET and POST. CGIs that use GET take their arguments from the URL. Programs that use POST read their arguments from standard input.
The second thing to know is that when you submit data to a form through a web browser, the web browser encodes the data for you. In an applet, however, you need to encode the data yourself. The data is encoded like this: Each form entry is a name-value pair. Names and values are separated from each other by equals signs (=). Pairs are separated from each other by ampersands (&). For example, consider this form:
<Form method=GET action="http://sunsite.unc.edu/javafaq/cgi-bin/getform.pl"> Email: <Input NAME="email" size=40> Name: <Input NAME="realname" size=40> <Input TYPE="submit" VALUE="Subscribe"> </Form>You see that this uses the GET method to communicate with a cgi-bin program at http://sunsite.unc.edu/javafaq/cgi-bin/getmaillist.pl. It sends two fields to the CGI program, email and realname. Let's say you want to send the string "elharo@sunsite.unc.edu" for the email address, and the string "Elliotte Harold" for the real name. Then the query string would look like this:
String qs = "email=elharo%40sunsite.unc.edu&realname=Elliotte%20Harold";
The spaces in "Elliotte Harold" and the @ in "elharo@sunsite.unc.edu" have been converted into percent escapes. All non-alphanumeric characters in the values must be replaced with a % followed by their ASCII value. Thus a space becomes %20 and the @ becomes %40.
To send this data to the server, append a question mark (?) and the query string to the URL of the CGI program, and request that URL from the server. Thus the URL you want is:
http://sunsite.unc.edu/javafaq/cgi-bin/getform.pl?email=elharo%40sunsite.unc.edu;realname=Elliotte%20Harold";
In Java terms this requires constructing a URL object from this string, and
opening that URL's InputStream to read the response. The following
code fragment demonstrates:
try {
String thisLine;
String qs = ""email=elharo%40sunsite.unc.edu&realname=Elliotte%20Harold";
URL u = new URL("http://sunsite.unc.edu/javafaq/cgi-bin/getform.pl?" + qqs);
DataInputStream theHTML = new DataInputStream(u.openStream());
while ((thisLine = theHTML.readLine()) != null) {
System.out.println(thisLine);
}
}
catch (Exception e) {
System.err.println(e);
}
Communicating with CGI programs that use POST is somewhat more
complex, and it doesn't work very well in Java 1.0.2. It may be
improved in Java 1.1. When POSTing to a CGI, you encode the query
string exactly as you do for GET requests. However instead of merely
requesting a URL's InputStream, you open a URLConnection to the CGI
program. Do not append the query string to the URL as you did with GET. Instead set the URLConnection's doOutput and doInput fields to true and set AllowUserInteraction to false. Chain the URLConnection's OutputStream to a DataOutputStream and use the DataOutputStream's writeBytes method to send the query string to the server.
If you want to read the response, then chain the URLConnection
's
InputStream
to a DataInputStream
, and use the DataInputStream
's
readLine()
method to read the response in a while
loop. The following
code fragment demonstrates:
String query = "email=elharo%40sunsite.unc.edu;realname=Elliotte%20Harold";
try {
// open the connection and prepare it to POST
URL u = new URL("http://sunsite.unc.edu/javafaq/cgi-bin/postform.pl");
URLConnection uc = u.openConnection();
uc.setDoOutput(true);
uc.setDoInput(true);
uc.setAllowUserInteraction(false);
DataOutputStream dos = new DataOutputStream(uc.getOutputStream());
// Send the data
dos.writeBytes(query);
dos.close();
// Read the response
DataInputStream dis = new DataInputStream(uc.getInputStream());
String nextline;
while((nextline = dis.readLine()) != null) {
System.out.println(nextline);
}
dis.close();
}
catch (Exception e) {
System.err.println(e);
}
As you see, posting forms is considerably more complex than using
the GET method. However on some platforms, GET has an annoying
habit of failing once the query string grows past 200 characters.
The exact point where GET fails varies depending on the operating
system and the web server.
The Simple Mail Transport Protocol is an Internet standard that you may be able to use some of the time. The basic idea is to open a socket to the SMTP port, 25, on the web server, and send your email through the server. However not all web servers, especially those based on Macs or Windows NT, run SMTP servers, and an applet can't open sockets to other hosts. Even if you do have SMTP software running on your web server, the applet may be behind a firewall that disallows outgoing connections to port 25 on hosts outside the firewall.
Unlike most random functions in other libraries the
Math.random()
method seeds itself with the current time
in milliseconds. Thus you do not need to seed it explicitly at the
start of your program. If you require a non-random Random()
for
test purposes or you need more randomness than the current time in
milliseconds can provide, then you can use java.util.Random() which
has a constructor that lets you specify a seed.
paint()
method. The pixels get put on the
screen in the update()
method which most applets don't override.
However by overriding the update method you can do all your painting
in an offscreen Image and then just copy the final Image onto the
screen with no visible flicker.
The cookbook approach is simple. Add the following three private
fields to your applet and the public update()
method. Flicker will
magically disappear.
private Image offScreenImage;
private Dimension offScreenSize;
private Graphics offScreenGraphics;
public final synchronized void update (Graphics g) {
Dimension d = size();
if((offScreenImage == null) || (d.width != offScreenSize.width) || (d.height != offScreenSize.height)) {
offScreenImage = createImage(d.width, d.height);
offScreenSize = d;
offScreenGraphics = offScreenImage.getGraphics();
}
paint(offScreenGraphics);
g.drawImage(offScreenImage, 0, 0, null);
}
The character that separates one directory from the next in a path
is called the separator character. It is a slash (/)
on Unix, a backslash (\) in Windows and a colon (:) on the Mac. You can
get its value on a particular platform by looking at the static
variable java.io.File.separatorCharacter
.
If you actually check this on the Mac, you'll note something funny.
java.io.File.separatorCharacter
appears to be a slash (/)
like on Unix,
no a colon like a Mac programmer would expect. Why this had to
be changed from every other Mac program in the universe
I don't know. This is problematic because
Mac file names can include slashes.
The CLASSPATH is an environment variable that contains a list of
directories where Java looks for classes referenced in a program. If
the CLASSPATH isn't set properly no program written in Java will be
able to run, and the compiler won't be able to compile. Each entry
in this list is separated from the other entries by the
java.io.File.pathSeparatorChar
. This is semicolon (;) on Unix
and Windows and a colon (:) on the Mac. For example
Unix:~/classes;/usr/local/netscape/classes
Windows:C:\java\classes;C:\netscape\classes
Mac:My Hard Drive/JDK/classes:My Hard Drive/My Project:My Hard Drive/classes
Java applets and applications aren't self-contained. They need
access to other classes to do their work. For instance when you call
System.out.println()
Java needs to know where to look
to find the file that includes the System
class.
The directories in the CLASSPATH are where Java starts searching for
classes. To find a class Java first changes the periods in the full
package-qualified name of the class (e.g. java.util.Date
and not
just Date
) into directory separators (/ on Unix, \ on Windows, : on
the Mac). Thus if it wants the java.awt.GridBagLayout
class, it
looks for the file java/awt/GridBagLayout.class
in each of the root
directories listed in the CLASSPATH variable from left to right
until it finds the file. With the Unix CLASSPATH listed above, Java
first looks for ~/classes/java/awt/GridBagLayout.class
Then for,
/usr/local/netscape/classes/java/awt/GridBagLayout.class
.
The specification of the CLASSPATH is somewhat platform dependent.
For instance ~ means the home directory on Unix but has no meaning
on the Mac.
Under Unix you set CLASSPATH variables like this:
csh: % setenv CLASSPATH my_class_path sh: % CLASSPATH=my_class_pathYou'll probably want to add one of these lines to your .login or .cshrc file so it will be automatically set every time.
Under Windows you set the CLASSPATH environment variable with a DOS command like
C:\> SET CLASSPATH=C:\JDK\JAVA\CLASSES;c:\java\lib\classes.zipYou gan also add this to your autoexec.bat file. You should of course point it at whichever directories actually conatin your classes.
The CLASSPATH variable is also important when you run Java applets, not just when you compile them. It tells the web browser or applet viewer where it should look to find the referenced .class files. If the CLASSPATH is set improperly, you'll probably see messages like "Applet could not start."
Since large packages can contain many, many .class files Sun has built the capability to read zip archives into Java. Therefore an entire directory structure of class files can be zipped to save space. If you want to see what's inside the zip file, unzip it. Java doesn't care whether or not a directory has been zipped. You just need to make sure that the .zip file is named the same as the directory it replaces plus the .zip extension and that it is in the same location.
In Netscape you should make sure that the first directory in the CLASSPATH is the directory that contains Netscape's class files (The defaults are /usr/local/netscape/java/classes on Unix and C:\NETSCAPE\NAVIGATOR\Program\java\classes in Windows.)
Finally note that if you install additional packages such as Jeeves or any third party package, you need to add the directory where the package is installed to your CLASSPATH. For example let's say you buy a package of statistics classes from SPSS, and you put those classes in /opt/classes/stats. Then you you need to add /opt/classes/stats to the end of your CLASSPATH.
You can temporarily add a directory to the CLASSPATH by giving the -classpath option to the java interpreter or the javac compiler. For example,
javac -classpath $CLASSPATH;/opt/classes/statsTo use just the classes in /opt/classes/stats and not the classes normally found in your CLASSPATH, omit $CLASSPATH like this:
javac -classpath /opt/classes/statsFinally if the CLASSPATH environment variable has not been set, and you do not specify one on the command line, then Java sets the CLASSPATH to the default:
Unix:Here . is the current directory and $JAVA is the main Java directory where the different tools like javac were installed..:$JAVA/classes:$JAVA/lib/classes.zip
Windows:.:$JAVA\classes:$JAVA\lib\classes.zip
Mac:./$JAVA:classes/$JAVA:lib:classes.zip
The other possibility is that the web server is sending the file to clients as text rather than binary data. Make sure the web server is configured to send files that end in ".class" with a MIME type of application/octet-stream. Many web servers send files as type text/plain which often works but causes problems on a few servers. In particular, WebStar needs to change the action to "binary" and the MIME type to "application/octet-stream".
init()
method many times more than the
appletviewer will. In particular Netscape calls init()
anytime
your reload, resize or otherwise restart your applet. I am not sure
whether or not this is a bug, but it does indicate that you should
try to keep your init()
methods as small and quick as possible.
Similarly it may call destroy()
when the applet viewer would only
call stop()
.
Object.clone()
.
System.out.println(Double(0.56).toString());
You must use the new
operator like:
Double myDouble = new Double(0.56);
System.out.println(myDouble.toString());
or
System.out.println((new Double(0.56)).toString());
In other words, constructors are only called after a
new
operator.
null
. The individual components of the array
must still be initialized with a constructor or an
assignment statement. For example, consider this statement:
Integer[] scores = new Integer[10];
int m = scores[5].intValue(); // throws NullPointerException
This creates an array called scores containing ten references
to Integer objects. Then it tries to get the value of the fifth component.
However, each of those references is initially set to null
.
Thus when you try to call a method on one of the components of the array or pass
the component to a method that expects a non-null argument,
a NullPointerException
is thrown. To fix this, you need to initialize the components of the array, either with constructors or with assignment statements For example:
Integer[] scores = new Integer[10];
for (int i = 0; i < scores.length; i++) scores[i] = new Integer(i);
int m = scores[5].intValue();
You do not need to initialize all the components of the array though
it's a good idea to do so. You can initialize just those you'll use,
or you can make sure you catch and handle
NullPointerException
s in the appropriate places.This is different from how Java handles uninitialized non-array reference variables. By way of contrast when you write,
Integer score;
int m = score.intValue();
the compiler catches the null
reference in
score
and complains. You have to fix the problem before
you can compile the program. However in general the compiler has no
way to know whether an array component has or has not been
initialized. Therefore the check for the non-nullness of an array
component is deferred till runtime when the
NullPointerException
may be thrown.
In Netscape the user doesn't even get the keys to the cage so you can't let the applets out into your system even if you wanted to. With the Applet Viewer it is possible to give your applets more access to the network. However they still can't do everything a C program can do.
Specifically a Java applet cannot write anything to a hard drive. It cannot write directly to memory, and it cannot introduce a virus into your system. A Java applet can use a lot of your CPU time though not 100% of it. It cannot crash your system (though a Java enabled browser can).
Finally an applet can display pictures or text or play sounds which the user may find annoying or offensive, but this hardly qualifies as a security flaw and is not unique to Java enabled browsers.
Natural Intelligence's Roaster is a Macintosh hosted applet development environment. It has been designed from the public specs with no help from Sun. It is also still beta quality. I do not recommend it.
Metrowerks includes Java support in Code Warrior Gold. Metrowerks has licensed Sun's source code. The Java support is alpha quality, and is not by itself worth the price of Code Warrior, even the $99 Java only edition. However if you also need a C compiler it doesn't cost you anymore to get Java support.
Sun publishes a payware IDE called Java Workshop. It is fairly cheap, ($99) but again not yet worth the download time. Java Workshop is similar to Sun's existing Workshop products for Fortran and C++. However it is written entirely in Java. You'll need at least a Pentium Pro to squeeze adequate performance out of this system.
Microsoft's Visual J++ is one of the faster VM/JIT combinations available. However the compiler has some bugs that prevent it from compiling certain legal Java code. Once again, despite the 1.0 designation this beta software at best, and is not worth spending money on.
Aleda Freeman has created an excellent page on Java IDE's and other tools at http://www.cybercom.net/~frog/javaide.html. This site has descriptions of and links to IDE's, database connectivity tools, and more.
The bottom line is that you should use Sun's JDK and the text editor of your choice. None of the available IDEs are worth what they cost. All will cause you more problems than they solve. Unless you enjoy paying to beta test products, there's no reason to purchase any of these at this time.
http://www.barebones.com/bbedit.html
However, in general any normal text or programmer's editor should be fine.
The Java source code is freely available for non-commercial use though a license must be signed. If you want to license the Java source code for commercial use you will need to pay $125,000 for the first platform, $25,000 per additional platform and a $2/unit royalty. Annual upgrades are $50,000 plus $5,000 for each additional platform. Complete details are at http://www.javasoft.com/java.sun.com/source.html.
Furthermore whether your product is commercial or non-commercial you may not use the trademark "Java" to describe your product unless you pass an as yet unreleased verification and test suite.
Why am I taking on such a Herculean task? It's often said that you never really understand a subject until you teach it. I'm going to endeavor to learn Java and understand it by teaching it. The result should be interesting at least. Since I'm very new to Java and clearly do not yet understand the language, I'll have a perspective on the issues that should be helpful to newcomers.
Are there mistakes here? Absolutely. I hope people here and elsewhere will correct me gently and help lead me on the path to true Java enlightenment when I err. And if they aren't so gentle, well, I've developed a pretty thick skin after five years of Usenet.
My companion tutorial in how to write Java is going to reflect the programs I'm actually writing. As I learn to do a Hello World program, I'll write about Hello World. (OK, I've actually already gotten beyond Hello World but not much beyond.) How fast the FAQ list grows will depend in large part on how fast my skills grow. You'll get to watch me learn, make mistakes, correct mistakes and so on.
There may be an advantage to this approach. People who want to learn Java will be coming from almost identical places as me. I always hate having to write down or talk down to people, and I don't do it very well. Similarly I find it frustrating to try to communicate with people who are way beyond me (as obviously some people on the Java mailing lists are). This means that I can write for people without much prior experience without boring myself or, hopefully, my audience, to tears.
Finally I'll emphasize that I'm not trying to prevent anyone else or any other team of people from taking on a similar project. I hope someone does. I'll probably learn from what they do, and they'll learn from what I do, even if it's only to learn the sorts of things novices are confused about. And of course not everyone shares the same learning style so while some people may enjoy my approach to Java I am sure others will find it dense, incoherent and ultimately incomprehensible. More choices are better.
Ultimately I'm doing this because I think Java is very, very cool and I am convinced I need to learn it sooner rather than later. I think this project will propel my Java knowledge forward, and if it does that I'll consider my project a success. If I can help a few other lost souls to climb out of the pit with me at the same time, so much the better.
However I do not allow the FAQ list, either the text or HTML version, to be placed on any web or ftp 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.
If you want to use the source code samples included here, please do. I consider the source code (though not the FAQ list itself!) to be public domain. No permission is necssary to reuse, edit, modify or publish any of the source code contained in this FAQ list.