In this chapter
Java (with a capital J) is a high-level, third generation programming language, like C, Fortran, Smalltalk, Perl, and many others. You can use Java to write computer applications that crunch numbers, process words, play games, store data or do any of the thousands of other things computer software can do.
Compared to other programming languages, Java is most similar to C. However although Java shares much of C's syntax, it is not C. Knowing how to program in C or, better yet, C++, (best of all: Objective C) will certainly help you to learn Java more quickly; but you don't need to know C to learn Java. Unlike C++, Java is not a superset of C. A Java compiler won't compile C code, and C programs need to be changed substantially before they can become Java programs.
|Technical Term: Compiler|
Occasionally I'm going to use sidebars like this one to explain some techno-babble like compiler that most programmers probably already know but novices may find a little confusing.
The reason we need compilers is that computers neither speak nor understand English, French, Arabic or any other language familiar to the carbon-based life forms known as "human beings". Instead computers understand languages that look like this:
This is called machine code. To make matters worse, just like different people use different languages, so too do different computers use different machine languages. Therefore the same program may be expressed in completely different ways on different kinds of computers.
In the early days (the 1950's) human beings had no choice but to learn to speak machine language because the computers were far too stupid to learn to speak human. Fifty years later computers still aren't smart enough to speak English, but humans have taught them to speak certain quasi-human languages like C and Java. The programs that translate these specialized programming languages into machine language are called compilers.
Compilers translate an entire program into machine language before it is run. Certain languages, most commonly Basic, are translated into machine language line-by-line as they are run. The programs that do this line-by-line translation are called interpreters and the languages that use them are called interpreted languages. Languages that are compiled (C is one) are called compiled languages. In general, compiled programs are about an order of magnitude faster than the equivalent interpreted program and use substantially less memory, especially for small programs.
So which is Java, interpreted or compiled? Actually it's both. The full story is a little more complicated than the nreof treatment given here, and will be discussed further below.
What's most special about Java in relation to other programming languages is that it lets you write special programs called applets that can be downloaded from the Internet and run safely within a web browser. Traditional computer programs have far too much access to your system to be downloaded and executed willy-nilly. Although you generally trust the maintainers of various FTP archives and bulletin boards to do basic virus checking and not to post destructive software, a lot still slips through the cracks. Even more dangerous software would be promulgated if any web page you visited could run programs on your system. You have no way of checking these programs for bugs or for out-and-out malicious behavior before downloading and running them.
Java solves this problem by severely restricting what an applet can do. A Java applet cannot write to your hard disk without your permission. It cannot write to arbitrary addresses in memory and thereby introduce a virus into your computer. It cannot crash your system.
|Hype Alert: System Crashes|
In theory an applet can't crash your system. In practice Java has not quite achieved this level of reliability yet. The inability to crash the system is heavily dependent on the crash-proofing of the system itself. Unix and Linux are quite resistant to crashing and Windows NT is almost as crash-proof. Windows 95, 98, and the Mac, however, are relatively easy to crash. Nonetheless all these systems are becoming more stable with each new release of Java, and the day is not too far in the future when you can stop worrying about buggy code bringing down your entire computer.
There's another problem with distributing executable programs from web pages. Computer programs are very closely tied to the specific hardware and operating system they run on. A Windows program will not run on a computer that only runs DOS. A Mac application can't run on a Unix workstation. VMS code can't be executed on an IBM mainframe, and so on. Therefore major commercial applications like Microsoft Word or Netscape Navigator have to be written almost independently for all the different platforms they run on. Netscape Navigator is one of the most cross-platform of major applications, and it still only runs on a minority of platforms.
|Technical Term: Platform|
A platform is a loosely defined computer industry buzzword that typically means some combination of hardware and system software that will mostly run all the same software. For instance PowerMacs running MacOS 8.5 would be one platform. Digital Alphas running Windows NT would be another.
Java solves the problem of platform-independence by using byte code. The Java compiler does not produce native executable code for a particular machine like a C compiler would. Instead it produces a special format called Java byte code. Java byte code looks like this
CA FE BA BE 00 03 00 2D 00 3E 08 00 3B 08 00 01 08 00 20 08
This looks a lot like machine language, but unlike machine language Java byte code is exactly the same on every platform. This byte code fragment means the same thing on a Solaris workstation as it does on a Macintosh PowerBook.
Java programs that have been compiled into byte code still need an interpreter to execute them on any given platform. The interpreter reads the byte code and translates it into the native language of the host machine on the fly. The most common such interpreter is Sun's program java (with a little j). Since the byte code is completely platform independent, only the interpreter and a few native libraries need to be ported to get Java to run on a new computer or operating system. The rest of the runtime environment including the compiler and most of the class libraries are written in Java, and are therefore platform independent themselves.
All these pieces, the javac compiler, the java interpreter, the Java programming language, and more are collectively referred to as Java. However this book restricts its usage of Java to mean only the Java programming language. It will be more specific and spell out the java interpreter or the Java environment when discussing those things.
Web page authors are excited about Java because of all the cool things it lets them do. Here are just a few things you can do on a web page with Java that you couldn't do before:
Java changes the Web from a static, fixed medium to a real-time interactive, dynamic, expandable multimedia environment.
Until Java, web pages were static. They had text and they had pictures but they had very little else, and they didn't change much. For the most part text and pictures just sat there. If you wanted to see something new, you clicked on a link and loaded an entirely new page. Then that page sat there, doing nothing.
Java makes web pages dynamic. By using Java you can make a page change while the user watches it. You can animate pictures. You can change the text that's displayed without reloading the entire page. For instance there have been stock price pages before Java, but it wasn't until Java that you could have a stock ticker page, i.e. a page that updated the price as the stock price changed. Figure 1-1 shows one such stock ticker applet.
|Hype Alert: Server Push|
Since this is an introductory book I am occasionally going to gloss over some fine points and make sweeping statements like "it wasn't until Java that you could have a stock ticker page, i.e. a page that updated the price as the stock price changed." If you want the clearest path through this book, please allow me to get away with the occasional misstatement. However since this is not Java for Dummies, I will expand on the point in blocks like these for those people who want the unexpurgated story.
In this case those of you who have been around the Web for a while will have noticed that there were in fact dynamically updated stock ticker applications using server push. However Java is better than server push for several reasons:
Server push gives you the choice of reloading an entire page or an image on the page. There is no way to change just a few pieces of text on the page, for instance the price of one stock.
Server push requires special support from the client and the server. For instance MacHTTP 2.2 and earlier and WebStar 1.0 and 1.1 did not support server push. (WebStar 1.2 and later do support server push.) Java only needs to be supported by the client. Any web server can serve Java pages.
Before Java users were limited to seeing the kinds of content their web browsers supported; and web developers were limited to the most basic content supported by their readers' web browsers, generally HTML 2.0 and GIF's. Java lets developers expand the range of content types indefinitely.
For instance, HotJava was the first web browser to include inline sound in a web page. Inline means that the sound plays inside the browser automatically. The reader doesn't need to launch a separate helper application to view it. The sound can play when the reader first visits a page, it can play when the reader clicks a button on a page, or it can play continuously in the background.
However Java is more than just a web browser with special features. Although HotJava was the first browser to include inline sound and animation, other browsers have long since added this feature.
What makes Java special is that it doesn't just allow you to add new types of content to pages like Netscape and Internet Explorer do. Rather it lets you add both the content and the code necessary to display that content. You no longer need to wait for a browser to be released that supports your preferred image format or special game protocol. With Java you send browsers both the content and the program necessary to view this content at the same time!
Think about what this means for a minute. Previously you had to wait for all the companies that make the web browsers your readers use to update their browsers before you could use a new content type. Then you had to hope that all your readers actually did update their browsers. Java compatibility is a feature that any browser can implement and, by so doing, implement every feature!
For instance suppose you want to use EPS files on your Web site. Previously you had to wait until at least one web browser implemented EPS support. Now you don't wait. Instead you can write your own code to view EPS files and send it to any client that requests your page at the same time they request the EPS file.
Or suppose you want people to be able to search your electronic card catalog. However the card catalog database exists on a mainframe system that doesn't speak HTTP. Before Java you could hope that some browser implemented your proprietary card catalog protocol; (fat chance) or you could try to program some intermediate CGI on a UNIX box that can speak HTTP and talk to the card catalog, not an easy task. With Java when a client wants to talk to your card catalog, you send them the code they need to do so. You don't have to try to force everything through an httpd server on port 80.
Before Java, people browsed the Web. They moved from site to site passively reading the text and viewing the pictures there, but they rarely interacted with the page or changed it in any meaningful way. Occasionally someone might fill out a form which would be submitted back to the server, but even that was slow and limited to typing text and making menu choices. This was hot stuff in 1975, but isn't so exciting in an era where users are accustomed to the interactivity of Quake.
After Java, users can use the keyboard for more than typing text and the mouse for more than choosing from menus. Instead of just reading a page and perhaps filling out a form, users can now play games, calculate spreadsheets, draw pictures, and in general do anything they might do within a window displayed by a traditional computer program. Most importantly users get immediate feedback. When you press enter in a spreadsheet cell, you don't want to wait for the entire spreadsheet to be sent back to the server and then the entire revised spreadsheet to be sent back to you. You want the update to happen instantaneously. With Java the calculations are performed on the client system and the results updated locally rather than remotely as would have to be done using a CGI program.
If that were all Java was, it would still be more interesting than a
<frame> tag in some new browser beta,
but there's a lot more. Java isn't just for web sites.
Java is a programming language that can do almost anything a traditional programming language like Fortran, Basic or C++ can do. However Java has learned from the mistakes of its predecessors. It is considerably easier to program and to learn than those languages without giving up any of their power.
The Java language shares many superficial similarities with C, C++, and Objective C. For instance, loops have identical syntax in all four languages, However, Java is not based on any of these languages, nor have efforts been made to make it compatible with them.
Java is sometimes referred to as C++++--. James Gosling invented Java because C++ proved inadequate for certain tasks. Since Java's 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 (the ++) and they threw away C++ features that had proven to be better in theory than in practice like multiple inheritance and operator overloading (the --). A few advanced features like closures and parameterized types that the Java team liked were nonetheless left out of the language due to time constraints. There's still argument over whether the right choices were made. Parameterized types (templates to C++ programmers) may be added in a later revision of Java.
Java has learned a lot from previous languages. Let's look at some of the advantages Java offers programmers.
Java was designed to make it much easier to write bug free code. According to Sun's Bill Joy, shipping C code has, on average, one bug per 55 lines of code. The most important part of helping programmers write bug-free code is keeping the language simple.
Java has the bare bones functionality needed to implement its rich feature set. It does not add lots of syntactic sugar or unnecessary features. The language specification for Java is only about eighty pages long compared to a couple of hundred pages for C and even more for C++. Despite its simplicity Java has considerably more functionality than C.
Because Java is simple, it is easy to read and write. Obfuscated Java isn't nearly as common as obfuscated C. There aren't a lot of special cases or tricks that will confuse beginners.
About half of the bugs in C and C++ programs are related to memory allocation
and deallocation. Therefore the second important addition Java makes to
providing bug-free code is automatic memory allocation and deallocation. The C
library memory allocation functions
free() are gone as are C++'s destructors.
Java is an excellent teaching language, and an excellent choice with which to learn programming. The language is small so it's easy to become fluent in it. The language is interpreted so the compile-link-run cycle is much shorter. (In fact, the link phase is eliminated entirely.) The runtime environment provides automatic memory allocation and garbage collection so there's less for the programmer to think about. Java is object-oriented (unlike Basic) so the beginning programmer doesn't have to unlearn bad programming habits when moving into real world projects. Finally, it's very difficult (if not quite impossible) to write a Java program that will crash your system, something that you can't say about any other language.
Object oriented programming was the catch phrase of computer programming in the 1990's. Although object oriented programming has been around in one form or another since the Simula language was invented in the 1960's, it really took hold in modern GUI environments like Windows, Motif and the Mac. In object-oriented programs data is represented by objects. Objects have two sections, fields (instance variables) and methods. Fields tell you what an object is. Methods tell you what an object does. These fields and methods are closely tied to the object's real world characteristics and behavior. When a program runs messages are passed back and forth between objects. When an object receives a message, it responds accordingly as defined by its methods.
Object oriented programming is alleged to have a number of advantages including:
In practice object-oriented programs have been just as slow, expensive and buggy as traditional non-object-oriented programs. In large part this is because the most popular object-oriented language is C++. C++ is a complex, difficult language that shares all the obfuscation of C while sharing none of C's efficiencies. It is possible in practice to write clean, easy-to-read Java code. In C++ this is almost unheard of outside of programming textbooks.
|For C Programmers: How Java differs from C and C++|
Java, unlike C++, is object-oriented at its core. Almost everything in
Java is either a class, a method, or an object. Only the most basic
primitive operations and data types (
There are no redundant features like structs, typedefs, and unions in Java. Since Java has classes it doesn't need them. C++ doesn't need them either, but they were kept in the language for compatibility with C (which does need them since it doesn't have classes). Bill Joy is fond of showing off a copy of Bjarne Stroustrup's The C++ Programming Language in which he's been highlighting all the sections that Java programmers don't need to concern themselves with. The last time I saw it almost half the book was highlighted and he wasn't finished yet.
There are no header files in Java. The Java compiler reads the actual source code to find out what's going on rather than relying on what the programmer thinks is going on. Functions only need to be declared where they're defined.
There is no operator overloading in Java. Experience has shown that as good as it sounded in theory, operator overloading is almost impossible to use in practice, especially in multi-person programming projects.
Methods in Java always occur inside the class they belong to. They may not be defined outside it as in C++. This is sensible for any object oriented language, but C++ was forced to do otherwise to maintain compatibility with legacy C code. In fact everything in Java happens inside a class. Unlike in C++ there are no functions sitting off in global space that do everything you forgot to do when you wrote the classes. Java almost forces clean, object oriented design on you.
There are no explicit pointers or pointer arithmetic in Java. Like global functions, pointers let you sneak through an object's access control. Similarly there are no friend functions in Java.
Finally, member functions in Java are virtual unless you specify otherwise. Polymorphism is the default.
Java was designed to not only 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 form called byte-code.
A Java program never really executes natively on the host machine. Rather a special native program called the Java interpreter reads the byte code and executes the corresponding native machine instructions. Thus to port Java programs to a new platform, all you need to do is run it with an interpreter written for the new platform. You don't even need to recompile. Even the compiler is written in Java. The byte codes are precisely defined, and remain the same on all platforms.
The second important part of Java's cross-platform savvy is the elimination of undefined and architecture dependent constructs. Integers are always four bytes long, and floating point variables follow the IEEE 754 standard for computer arithmetic exactly. You don't have to worry that the meaning of an integer is going to change if you move from a Pentium to a PowerPC. In Java everything is guaranteed.
However the virtual machine itself and some parts of the class library must be written in native code. These are not always as easy or as quick to port as pure Java programs. This is why for example, there's not yet a version of Java 1.2 for the Mac.
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 many features of C and C++. Most notably
there are no pointers in Java. Java programs cannot access arbitrary addresses
in memory. All memory access is handled behind the scenes by the (presumably)
trusted runtime environment. Furthermore Java has strong typing. Variables must
be declared, and variables do not change types when you aren't looking. Casts
are strictly limited to casts between types that make sense. Thus you can cast
int to a
long or a
byte to a
short but not a
long to a
boolean or an
int to a
Java implements a robust exception handling mechanism to deal with both expected and unexpected errors. The worst that a Java program can do to a host system is bring down the runtime environment. It cannot bring down the entire system.
Most importantly Java applets can be executed in an environment that prohibits them from introducing viruses, deleting or modifying files, or otherwise destroying data and crashing the host computer. A Java enabled web browser checks the byte codes of an applet to verify that it doesn't do anything nasty before it will run the applet.
However the biggest security problem is not hackers. It's not viruses. It's not Visual Basic worms transmitted by Outlook Express. It's not even insiders erasing their hard drives and quitting your company to go to work for your competitors. No, the biggest security issue in computing today is bugs. Regular, ordinary, non-malicious, unintended bugs are responsible for more data loss and lost productivity than all other factors combined. Java, by making it easier to write bug-free code, substantially improves the security of all kinds of programs.
Java byte codes can be compiled on the fly to code that rivals C++ in speed using a "just-in-time compiler." Several companies are also working on native-machine-architecture compilers for Java. These will produce executable code that does not require a separate interpreter, and that is indistinguishable in speed from C++. While you'll never get that last ounce of speed out of a Java program that you might be able to wring from C or Fortran, the results will be suitable for all but the most demanding applications.
As of May, 1999, the fastest VM, IBM's Java 1.1 VM for Windows, is very close to C++ on CPU-intensive operations that don't involve a lot of disk I/O or GUI work; C++ is itself only a few percent slower than C or Fortran on CPU intensive operations.
It is certainly possible to write large programs in Java. The HotJava web browser, the JBuilder integrated development environment and the javac compiler are large programs that are written entirely in Java.
Java is inherently multi-threaded. A single Java program can have many different processes executing independently and continuously. Three Java applets on the same page can run simultaneously with each getting equal time from the CPU with very little extra effort on the part of the programmer. This makes Java incredibly responsive to user input. It also helps to contribute to Java's robustness and provides a mechanism whereby the Java environment can ensure that a malicious applet doesn't steal all of the host's CPU cycles.
Unfortunately multithreading is so tightly integrated with Java, that it makes Java rather difficult to port to architectures like Windows 3.1 or the PowerMac that don't natively support preemptive multi-threading.
There is another cost associated with multi-threading. Multi-threading is to Java what pointer arithmetic is to C; that is, a source of devilishly hard to find bugs. Nonetheless, in simple programs it's possible to leave multi-threading alone and normally be OK.
Java does not have an explicit link phase. Java source code is divided into .java files, roughly one per each class in your program. The compiler compiles these into .class files containing byte code. Each .java file generally produces exactly one .class file. (There are a few exceptions we'll discuss later, non-public classes and inner classes).
The compiler searches the current directory and a few other well specified places to find other classes explicitly referenced by name in each source code file. If the file you're compiling depends on other, non-compiled files, then the compiler will try to find them and compile them as well. The Java compiler is quite smart, and can handle circular dependencies as well as methods that are used before they're declared. It also can determine whether a source code file has changed since the last time it was compiled.
More importantly, classes that were unknown to a program when it was compiled can still be loaded into it at runtime. For example, a web browser can load applets of differing classes that it's never seen before without recompilation.
Furthermore, Java .class files tend to be quite small, a few kilobytes at most. It is not necessary to link in large runtime libraries to produce an executable. Instead the necessary classes are loaded from the user's local system.
You do not need to explicitly allocate or deallocate memory
in Java. Memory is allocated as needed, both on the stack and
the heap, and reclaimed by the garbage collector when it is no
longer needed. There are no
free(), or destructor methods. There are
constructors and these do allocate memory on the heap, but this
is transparent to the programmer.
Most Java virtual machines use an inefficient, mark and sweep garbage collector. Some more recent virtual machines have improved matters quite a bit by using generational garbage collection.
To sum up, Java is a safe, robust, garbage-collected, object-oriented, high-performance, multi-threaded, interpreted, architecture-neutral, cross-platform, buzzword-compliant programming language.
In the late 1970's Bill Joy thought about doing a language that would merge the best features of MESA, an experimental language from Xerox, and C. However other projects (like cofounding Sun) intervened. In the late 1980's he got Sun's engineers started on a complete revision of the UNIX operating system that involved merging SunOS 4.x with AT&T's SYSVR4.
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 pitched Sun engineers on the idea that they should produce an object environment based on C++. Today, however, Joy freely admits that C++ was too complicated and not up to the job.
Patrick Naughton, then of Sun, later 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.
Around this time Sun Distinguished Scientist 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. Gosling claims that he named Oak when he looked out his window and saw a tree. However early Sun papers refer to Oak as the "Object Architecture Kernel." It is unknown whether the name or the acronym came first. In either case the Oak name did not survive a trademark search and was changed to Java in 1995.
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 Naughton 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. In October of 1992 this was demoed to Scott McNealy, Sun's president, who 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 settop 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. Patrick Naughton wrote a prototype browser called WebRunner in one weekend of inspired hacking. After additional work by Naughton and Jonathan Payne this eventually became HotJava. The rest, as they say, is history.
This chapter has given you a basic overview of why Java is so exciting. The things you learned in this chapter included:
In the next chapter you'll download and install the software you need to run Java programs. In later chapters you'll learn all the practical details of Java's advanced language features like objects and multi-threading that were discussed theoretically in this chapter. You'll learn how to write your own applets like WallStreetWeb. Get ready. Your journey into Java is about to begin.
Q: What can't I do with Java?
A: If you believed everything you read in this chapter unconditionally, please contact the author about a certain bridge he has for sale near his home in Brooklyn, cheap. On the other hand if you're understandably a bit skeptical about whether Java really is the greatest tool since Mosaic, let me point out a few weaknesses:
Q: Leaving implementation issues aside, Is Java the perfect language?
A: Once again there are a few weaknesses to be pointed out:
intaren't objects. This makes data structures such as linked lists that need to hold both objects and primitive data relatively hard to implement and quite cumbersome overall. It also leads to problems with numeric overflow.
ArithmeticExceptions rather than returning
NaN. Furthermore, the specific implementation of the IEEE 754 floating point model Sun chose is much better suited to Sun's Sparc processors than to X86 or PowerPC CPUs.
casestatement is insufficiently expressive to handle even a majority of the "Choose one of several options" blocks you're likely to encounter.
\tto insert them.
caseexecutes all cases that follow the matched
caseunless there's an explicit
Q: Can Java be used by non-programmers?
A: Java isn't just for programmers. Just like you can write text with Microsoft Word without knowing how to write in C++, you can add animations, sounds and other cool Java stuff to your web pages without writing a line of code, just by using other people's applets. However this book is written for people who want to program in Java, and from here on in it will concentrate on developing the skills you need to write your own unique programs.
Q: What's HotJava? Where does it fit in?
A: HotJava is a particular web browser from Sun Microsystems that can play Java applets. It is not the only one. Netscape Navigator and Microsoft Internet Explorer can also run Java applets.
Q: Couldn't a browser plug-in be used to to do all the cool stuff an applet can do?
A: In theory plug-ins can do a lot. However they cannot be downloaded and installed into a user's system on the fly when they visit a web page. Imagine if every web site you visited required a new plug in. Furthermore plug-ins are platform specific. you need to write a plug-in for every platform that may be used by someone visiting your pages. Plug-ins are generally faster than Java applets though and don't have as many security restrictions. Therefore plug-ins are good if you're writing something that will be used by many web unrelated web sites and you have the resources to support a dozen or more platforms equally. However if what you're creating is unique to your site or you don't want to port your software to a dozen platforms, then you should write it as a Java applet.
Q: Couldn't Flash to do all the cool stuff an applet can do?
A: Yes, Macromedia Flash can probably do just about everything an applet can do, and it may do it better too. However, Flash is just for applets. Java has a lot more to offer than applets on web pages.
Sun's web site has several white papers about the philosophy of Java. The most comprehensive one often referred to simply as "The White Paper", is:
Gosling, James and Henry McGilton, The Java Language Environment, A White Paper, May 1996, http://java.sun.com/docs/white/langenv/.
Though doubtless one day tomes will be written about the genesis of Java and the Green project will be mentioned in the same hushed tones now reserved for the Home Brew Computer Club, not much has yet been written about the history of Java. Most of the details are being passed around by word of mouth. However there have been a couple of decent articles about the genesis of Java. See
Bank, David, "The Java Saga," Wired, December 1995, pp. 166-169, http://www.hotwired.com/wired/3.12/features/java.saga.html
O'Connell, Michael, "Java: The inside story," SunWorld Online, July 1995, http://www.sun.com/sunworldonline/swol-07-1995/swol-07-java.html
So far only one of the original members of the Green Project has written about it publicly. For a rather surprising look at how the Green Project operated and how Java almost didn't happen see
Naughton, Patrick, "The Long Strange Trip to Java," The Java Handbook, pp 391-409, Berkeley: Osborne McGraw-Hill, 1996
This is the first book-length treatment about the origins of Java. Doubtless there'll be others as time passes. It focuses on the personalities and squabbles as oppose to the technology.
Marlowe, Jos and Richard J. Stiller, Asunder: An Unauthorized History of the Origins of Java Programming Language, Briarwood Publications, 1996
Not everyone agrees that C++ is as horrible as is argued here. For an interesting alternative viewpoint you should read The Design and Evolution of C++ by Bjarne Stroustrup, the inventor of C++. It's a fascinating look at why C++ is what it is, for good or bad.
Stroustrup, Bjarne, The Design and Evolution of C++, New York: Addison-Wesley, 1995