Java is a new language, but it draws on many years of programming experience with other languages in its choice of features. So a lot can be said in comparing and contrasting Java with other languages. There are at least three pillars necessary to support a universal language for network programming today: portability, speed, and security. Figure 1.2 shows how Java compares to other languages.
You may have heard that Java is a lot like C or C++, but that's really not true, except at a superficial level. When you first look at Java code, you'll see that the basic syntax looks a lot like C or C++. But that's where the similarities end. Java is by no means a direct descendant of C or a next generation C++. If you compare language features, you'll see that Java actually has more in common with languages like Smalltalk and Lisp. In fact, Java's implementation is about as far from native C as you can imagine.
The surface-level similarities to C and C++ are worth noting, however. Java borrows heavily from C and C++ syntax, so you'll see lots of familiar language constructs, including an abundance of curly braces and semicolons. Java also subscribes to the C philosophy that a good language should be compact; in other words, it should be sufficiently small and regular so that a programmer can hold all the language's capabilities in his or her head at once. As C is extensible with libraries, packages of Java classes can be added to the core language components.
C has been successful because it provides a reasonably featureful programming environment, with high performance and an acceptable degree of portability. Java also tries to balance functionality, speed, and portability, but it does so in a very different way. While C trades functionality to get portability, Java trades speed for portability. Java also addresses security issues, while C doesn't.
Java is an interpreted language, so it won't be as fast as a compiled language like C. But Java is fast enough, especially for interactive, network-based applications, where the application is often idle, waiting for the user to do something or waiting for data from the network. For situations where speed is critical, a Java implementation can optimize performance by compiling byte-code to native machine code on the fly.
Scripting languages, like Tcl, Perl, and Wksh, are becoming quite popular, and for good reason. There's no reason a scripting language could not be suitable for safe, networked applications (e.g., Safe Tcl), but most scripting languages are not designed for serious, large-scale programming. The attraction to scripting languages is that they are dynamic; they are powerful tools for rapid prototyping. Some scripting languages, like awk and Perl, also provide powerful tools for text-processing tasks more general-purpose languages find unwieldy. Scripting languages are also highly portable.
One problem with scripting languages, however, is that they are rather casual about program structure and data typing. Most scripting languages (with a hesitant exception for Perl 5.0) are not object oriented. They also have vastly simplified type systems and generally don't provide for sophisticated scoping of variables and functions. These characteristics make them unsuitable for building large, modular applications. Speed is another problem with scripting languages; the high-level, fully interpreted nature of these languages often makes them quite slow.
Java offers some of the essential advantages of a scripting language, along with the added benefits of a lower-level language. Incremental development with object-oriented components, combined with Java's simplicity, make it possible to develop applications rapidly and change them easily, with a short concept to implementation time. Java also comes with a large base of core classes for common tasks such as building GUIs and doing network communications. But along with these features, Java has the scalability and software-engineering advantages of more static languages. It provides a safe structure on which to build higher-level networked tools and languages.
As I've already said, Java is similar in design to languages like Smalltalk and Lisp. However, these languages are used mostly as research vehicles, rather than for developing large-scale systems. One reason is that they never developed a standard portable binding to operating-system services analogous to the C standard library or the Java core classes. Smalltalk is compiled to an interpreted byte-code format, and it can be dynamically compiled to native code on the fly, just like Java. But Java improves on the design by using a byte-code verifier to ensure the correctness of Java code. This verifier gives Java a performance advantage over Smalltalk because Java code requires fewer run-time checks. Java's byte-code verifier also helps with security issues, something that Smalltalk doesn't address. Smalltalk is a mature language though, and Java's designers took lessons from many of its features.
Throughout the rest of this chapter, we'll take a bird's eye view of the Java language. I'll explain what's new and what's not so new about Java; how it differs from other languages, and why.