Chapter 1
■
An Introduction to Java
6
The virtual machine has other advantages. It increases security because the virtual
machine can check the behavior of instruction sequences. Some programs even produce
bytecodes on the fly, dynamically enhancing the capabilities of a running program.
Portable
Unlike C and C++, there are no “implementation-dependent” aspects of the specifi-
cation. The sizes of the primitive data types are specified, as is the behavior of arith-
metic on them.
For example, an
int
in Java is always a 32-bit integer. In C/C++,
int
can mean a 16-bit
integer, a 32-bit integer, or any other size that the compiler vendor likes. The only
restriction is that the
int
type must have at least as many bytes as a
short int
and cannot
have more bytes than a
long int
. Having a fixed size for number types eliminates a major
porting headache. Binary data is stored and transmitted in a fixed format, eliminating
confusion about byte ordering. Strings are saved in a standard Unicode format.
The libraries that are a part of the system define portable interfaces. For example,
there is an abstract Window class and implementations of it for UNIX, Windows,
and the Macintosh.
As anyone who has ever tried knows, it is an effort of heroic proportions to write a pro-
gram that looks good on Windows, the Macintosh, and ten flavors of UNIX. Java 1.0
made the heroic effort, delivering a simple toolkit that mapped common user interface
elements to a number of platforms. Unfortunately, the result was a library that, with a
lot of work, could give barely acceptable results on different systems. (And there were
often different bugs on the different platform graphics implementations.) But it was a
start. There are many applications in which portability is more important than user
interface slickness, and these applications did benefit from early versions of Java. By
now, the user interface toolkit has been completely rewritten so that it no longer relies
on the host user interface. The result is far more consistent and, we think, more attrac-
tive than in earlier versions of Java.
Interpreted
The Java interpreter can execute Java bytecodes directly on any machine to which
the interpreter has been ported. Since linking is a more incremental and lightweight
process, the development process can be much more rapid and exploratory.
Incremental linking has advantages, but its benefit for the development process is
clearly overstated. Early Java development tools were, in fact, quite slow. Today, the
bytecodes are translated into machine code by the just-in-time compiler.
High Performance
While the performance of interpreted bytecodes is usually more than adequate,
there are situations where higher performance is required. The bytecodes can be
translated on the fly (at runtime) into machine code for the particular CPU the
application is running on.
In the early years of Java, many users disagreed with the statement that the perfor-
mance was “more than adequate.” Today, however, the just-in-time compilers have
become so good that they are competitive with traditional compilers and, in some cases,
even outperform them because they have more information available. For example, a
just-in-time compiler can monitor which code is executed frequently and optimize just
Chapter 1. An Introduction to Java