History and evolution of Java
The History and Evolution
of Java
To fully understand Java, one must understand the reasons behind its creation, the forces that
shaped it, and the legacy that it inherits. Like the successful computer languages that came before,
Java is a blend of the best elements of its rich heritage combined with the innovative concepts
required by its unique mission. While the remaining chapters of this book describe the practical
aspects of Java—including its syntax, key libraries, and applications—this chapter explains how
and why Java came about, what makes it so important, and how it has evolved over the years.
Although Java has become inseparably linked with the online environment of the Internet, it is
important to remember that Java is first and foremost a programming language. Computer language
innovation and development occurs for two fundamental reasons:
• To adapt to changing environments and uses
• To implement refinements and improvements in the art of programming
As you will see, the development of Java was driven by both elements in nearly equal measure.
Java’s Lineage
Java is related to C++, which is a direct descendant of C. Much of the character of Java is inherited
from these two languages. From C, Java derives its syntax. Many of Java’s objectoriented features
were influenced by C++. In fact, several of Java’s defining characteristics come from—or are
responses to—its predecessors. Moreover, the creation of Java was deeply rooted in the process of
refinement and adaptation that has been occurring in computer programming languages for the past
several decades. For these reasons, this section reviews the sequence of events and forces that led to
Java. As you will see, each innovation in language design was driven by the need to solve a
fundamental problem that the preceding languages could not solve. Java is no exception.
4
PART I
The Java Language
The Birth of Modern Programming: C
The C language shook the computer world. Its impact should not be underestimated, because it
fundamentally changed the way programming was approached and thought about. The creation of C
was a direct result of the need for a structured, efficient, high-level language that could replace
assembly code when creating systems programs. As you probably know, when a computer language
is designed, trade-offs are often made, such as the following:
• Ease-of-use versus power
• Safety versus efficiency
• Rigidity versus extensibility
Prior to C, programmers usually had to choose between languages that optimized one set of traits
or the other. For example, although FORTRAN could be used to write fairly efficient programs for
scientific applications, it was not very good for system code. And while BASIC was easy to learn, it
wasn’t very powerful, and its lack of structure made its usefulness questionable for large programs.
Assembly language can be used to produce highly efficient programs, but it is not easy to learn or use
effectively. Further, debugging assembly code can be quite difficult.
Another compounding problem was that early computer languages such as BASIC, COBOL, and
FORTRAN were not designed around structured principles. Instead, they relied upon the GOTO as a
primary means of program control. As a result, programs written using these languages tended to
produce “spaghetti code”—a mass of tangled jumps and conditional branches that make a program
virtually impossible to understand. While languages like Pascal are structured, they were not
designed for efficiency, and failed to include certain features necessary to make them applicable to a
wide range of programs. (Specifically, given the standard dialects of Pascal available at the time, it
was not practical to consider using Pascal for systems-level code.)
So, just prior to the invention of C, no one language had reconciled the conflicting attributes that
had dogged earlier efforts. Yet the need for such a language was pressing. By the early 1970s, the
computer revolution was beginning to take hold, and the demand for software was rapidly outpacing
programmers’ ability to produce it. A great deal of effort was being expended in academic circles in
an attempt to create a better computer language. But, and perhaps most importantly, a secondary
force was beginning to be felt. Computer hardware was finally becoming common enough that a
critical mass was being reached. No longer were computers kept behind locked doors. For the first
time, programmers were gaining virtually unlimited access to their machines. This allowed the
freedom to experiment. It also allowed programmers to begin to create their own tools. On the eve of
C’s creation, the stage was set for a quantum leap forward in computer languages.
Invented and first implemented by Dennis Ritchie on a DEC PDP-11 running the UNIX
operating system, C was the result of a development process that started with an older language
called BCPL, developed by Martin Richards. BCPL influenced a language called B, invented by Ken
Thompson, which led to the development of C in the 1970s. For many years, the de facto standard
for C was the one supplied with the UNIX operating system and described in The C Programming
Language by Brian Kernighan and Dennis Ritchie (PrenticeHall, 1978). C was formally standardized
5
PART I
The Java Language
in December 1989, when the American National Standards Institute (ANSI) standard for C was
adopted.
Chapter 1
The History and Evolution of Java
The creation of C is considered by many to have marked the beginning of the modern age of
computer languages. It successfully synthesized the conflicting attributes that had so troubled earlier
languages. The result was a powerful, efficient, structured language that was relatively easy to learn.
It also included one other, nearly intangible aspect: it was a programmer’s language. Prior to the
invention of C, computer languages were generally designed either as academic exercises or by
bureaucratic committees. C is different. It was designed, implemented, and developed by real,
working programmers, reflecting the way that they approached the job of programming. Its features
were honed, tested, thought about, and rethought by the people who actually used the language. The
result was a language that programmers liked to use. Indeed, C quickly attracted many followers
who had a near-religious zeal for it. As such, it found wide and rapid acceptance in the programmer
community. In short, C is a language designed by and for programmers. As you will see, Java
inherited this legacy.
C++: The Next Step
During the late 1970s and early 1980s, C became the dominant computer programming language,
and it is still widely used today. Since C is a successful and useful language, you might ask why a
need for something else existed. The answer is complexity. Throughout the history of programming,
the increasing complexity of programs has driven the need for better ways to manage that
complexity. C++ is a response to that need. To better understand why managing program complexity
is fundamental to the creation of C++, consider the following.
Approaches to programming have changed dramatically since the invention of the computer. For
example, when computers were first invented, programming was done by manually toggling in the
binary machine instructions by use of the front panel. As long as programs were just a few hundred
instructions long, this approach worked. As programs grew, assembly language was invented so that a
programmer could deal with larger, increasingly complex programs by using symbolic representations
of the machine instructions. As programs continued to grow, high-level languages were introduced that
gave the programmer more tools with which to handle complexity.
The first widespread language was, of course, FORTRAN. While FORTRAN was an impressive
first step, it is hardly a language that encourages clear and easy-to-understand programs. The 1960s
gave birth to structured programming. This is the method of programming championed by languages
such as C. The use of structured languages enabled programmers to write, for the first time,
moderately complex programs fairly easily. However, even with structured programming methods,
once a project reaches a certain size, its complexity exceeds what a programmer can manage. By the
early 1980s, many projects were pushing the structured approach past its limits. To solve this
problem, a new way to program was invented, called object-oriented programming (OOP). Objectoriented programming is discussed in detail later in this book, but here is a brief definition: OOP is a
programming methodology that helps organize complex programs through the use of inheritance,
encapsulation, and polymorphism.
In the final analysis, although C is one of the world’s great programming languages, there is a
limit to its ability to handle complexity. Once the size of a program exceeds a certain point, it
becomes so complex that it is difficult to grasp as a totality. While the precise size at which this
6
Chapter 1
The History and Evolution of Java
occurs differs, depending upon both the nature of the program and the programmer, there is always a
threshold at which a program becomes unmanageable.
7
8
PART I
The Java Language
C++ added features that enabled this threshold to be broken, allowing programmers to comprehend
and manage larger programs.
C++ was invented by Bjarne Stroustrup in 1979, while he was working at Bell Laboratories in
Murray Hill, New Jersey. Stroustrup initially called the new language “C with Classes.” However, in
1983, the name was changed to C++. C++ extends C by adding object-oriented features. Because
C++ is built on the foundation of C, it includes all of C’s features, attributes, and benefits. This is a
crucial reason for the success of C++ as a language. The invention of C++ was not an attempt to
create a completely new programming language. Instead, it was an enhancement to an already highly
successful one.
The Stage Is Set for Java
By the end of the 1980s and the early 1990s, object-oriented programming using C++ took hold.
Indeed, for a brief moment it seemed as if programmers had finally found the perfect language.
Because C++ blended the high efficiency and stylistic elements of C with the object-oriented
paradigm, it was a language that could be used to create a wide range of programs. However, just as
in the past, forces were brewing that would, once again, drive computer language evolution forward.
Within a few years, the World Wide Web and the Internet would reach critical mass. This event
would precipitate another revolution in programming.
The Creation of Java
Java was conceived by James Gosling, Patrick Naughton, Chris Warth, Ed Frank, and Mike Sheridan
at Sun Microsystems, Inc. in 1991. It took 18 months to develop the first working version. This
language was initially called “Oak,” but was renamed “Java” in 1995. Between the initial
implementation of Oak in the fall of 1992 and the public announcement of Java in the spring of
1995, many more people contributed to the design and evolution of the language. Bill Joy, Arthur
van Hoff, Jonathan Payne, Frank Yellin, and Tim Lindholm were key contributors to the maturing of
the original prototype.
Somewhat surprisingly, the original impetus for Java was not the Internet! Instead, the primary
motivation was the need for a platform-independent (that is, architecture-neutral) language that
could be used to create software to be embedded in various consumer electronic devices, such as
microwave ovens and remote controls. As you can probably guess, many different types of CPUs
are used as controllers. The trouble with C and C++ (and most other languages) is that they are
designed to be compiled for a specific target. Although it is possible to compile a C++ program for
just about any type of CPU, to do so requires a full C++ compiler targeted for that CPU. The
problem is that compilers are expensive and time-consuming to create. An easier—and more costefficient—solution was needed. In an attempt to find such a solution, Gosling and others began
work on a portable, platform-independent language that could be used to produce code that would
run on a variety of CPUs under differing environments. This effort ultimately led to the creation of
Java.
About the time that the details of Java were being worked out, a second, and ultimately more
important, factor was emerging that would play a crucial role in the future of Java. This second force
9
PART I
The Java Language
was, of course, the World Wide Web. Had the Web not taken shape at about the same time that Java
was being implemented, Java might have remained a useful but obscure language for programming
consumer electronics. However, with the emergence
Chapter 1
The History and Evolution of Java
10
of the World Wide Web, Java was propelled to the forefront of computer language design, because
the Web, too, demanded portable programs.
Most programmers learn early in their careers that portable programs are as elusive as they are
desirable. While the quest for a way to create efficient, portable (platform-independent) programs is
nearly as old as the discipline of programming itself, it had taken a back seat to other, more pressing
problems. Further, because (at that time) much of the computer world had divided itself into the three
competing camps of Intel, Macintosh, and UNIX, most programmers stayed within their fortified
boundaries, and the urgent need for portable code was reduced. However, with the advent of the
Internet and the Web, the old problem of portability returned with a vengeance. After all, the Internet
consists of a diverse, distributed universe populated with various types of computers, operating
systems, and CPUs. Even though many kinds of platforms are attached to the Internet, users would
like them all to be able to run the same program. What was once an irritating but lowpriority problem
had become a high-profile necessity.
By 1993, it became obvious to members of the Java design team that the problems of portability
frequently encountered when creating code for embedded controllers are also found when attempting
to create code for the Internet. In fact, the same problem that Java was initially designed to solve on a
small scale could also be applied to the Internet on a large scale. This realization caused the focus of
Java to switch from consumer electronics to Internet programming. So, while the desire for an
architecture-neutral programming language provided the initial spark, the Internet ultimately led to
Java’s large-scale success.
As mentioned earlier, Java derives much of its character from C and C++. This is by intent. The
Java designers knew that using the familiar syntax of C and echoing the object-oriented features of
C++ would make their language appealing to the legions of experienced C/C++ programmers. In
addition to the surface similarities, Java shares some of the other attributes that helped make C and
C++ successful. First, Java was designed, tested, and refined by real, working programmers. It is a
language grounded in the needs and experiences of the people who devised it. Thus, Java is a
programmer’s language. Second, Java is cohesive and logically consistent. Third, except for those
constraints imposed by the Internet environment, Java gives you, the programmer, full control. If you
program well, your programs reflect it. If you program poorly, your programs reflect that, too. Put
differently, Java is not a language with training wheels. It is a language for professional
programmers.
Because of the similarities between Java and C++, it is tempting to think of Java as simply the
“Internet version of C++.” However, to do so would be a large mistake. Java has significant practical
and philosophical differences. While it is true that Java was influenced by C++, it is not an enhanced
version of C++. For example, Java is neither upwardly nor downwardly compatible with C++. Of
course, the similarities with C++ are significant, and if you are a C++ programmer, then you will feel
right at home with Java. One other point: Java was not designed to replace C++. Java was designed
to solve a certain set of problems. C++ was designed to solve a different set of problems. Both will
coexist for many years to come.
As mentioned at the start of this chapter, computer languages evolve for two reasons: to adapt to
changes in environment and to implement advances in the art of programming. The environmental
change that prompted Java was the need for platform-independent programs destined for distribution
on the Internet. However, Java also embodies changes in the way that people approach the writing of
Chapter 1
The History and Evolution of Java
11
programs. For example, Java enhanced and refined the object-oriented paradigm used by C++, added
integrated support for multithreading, and provided a library that simplified Internet access. In the
final analysis,
12
PART I
The Java Language
though, it was not the individual features of Java that made it so remarkable. Rather, it was the
language as a whole. Java was the perfect response to the demands of the then newly emerging,
highly distributed computing universe. Java was to Internet programming what C was to system
programming: a revolutionary force that changed the world.
The C# Connection
The reach and power of Java continues to be felt in the world of computer language development.
Many of its innovative features, constructs, and concepts have become part of the baseline for any
new language. The success of Java is simply too important to ignore.
Perhaps the most important example of Java’s influence is C#. Created by Microsoft to support
the .NET Framework, C# is closely related to Java. For example, both share the same general syntax,
support distributed programming, and utilize the same object model. There are, of course,
differences between Java and C#, but the overall “look and feel” of these languages is very similar.
This “cross-pollination” from Java to C# is the strongest testimonial to date that Java redefined the
way we think about and use a computer language.
How Java Changed the Internet
The Internet helped catapult Java to the forefront of programming, and Java, in turn, had a profound
effect on the Internet. In addition to simplifying web programming in general, Java innovated a new
type of networked program called the applet that changed the way the online world thought about
content. Java also addressed some of the thorniest issues associated with the Internet: portability and
security. Let’s look more closely at each of these.
Java Applets
An applet is a special kind of Java program that is designed to be transmitted over the Internet and
automatically executed by a Java-compatible web browser. Furthermore, an applet is downloaded on
demand, without further interaction with the user. If the user clicks a link that contains an applet, the
applet will be automatically downloaded and run in the browser. Applets are intended to be small
programs. They are typically used to display data provided by the server, handle user input, or
provide simple functions, such as a loan calculator, that execute locally, rather than on the server. In
essence, the applet allows some functionality to be moved from the server to the client.
The creation of the applet changed Internet programming because it expanded the universe of
objects that can move about freely in cyberspace. In general, there are two very broad categories of
objects that are transmitted between the server and the client: passive information and dynamic,
active programs. For example, when you read your e-mail, you are viewing passive data. Even when
you download a program, the program’s code is still only passive data until you execute it. By
contrast, the applet is a dynamic, self-executing program. Such a program is an active agent on the
client computer, yet it is initiated by the server.
As desirable as dynamic, networked programs are, they also present serious problems in the
areas of security and portability. Obviously, a program that downloads and executes automatically
13
PART I
The Java Language
on the client computer must be prevented from doing harm. It must also be able to run in a variety of
different environments and under different operating systems. As you will see, Java solved these
problems in an effective and elegant way. Let’s look a bit more closely at each.
Chapter 1
The History and Evolution of Java
14
Security
As you are likely aware, every time you download a “normal” program, you are taking a risk,
because the code you are downloading might contain a virus, Trojan horse, or other harmful code. At
the core of the problem is the fact that malicious code can cause its damage because it has gained
unauthorized access to system resources. For example, a virus program might gather private
information, such as credit card numbers, bank account balances, and passwords, by searching the
contents of your computer’s local file system. In order for Java to enable applets to be downloaded
and executed on the client computer safely, it was necessary to prevent an applet from launching
such an attack.
Java achieved this protection by confining an applet to the Java execution environment and not
allowing it access to other parts of the computer. (You will see how this is accomplished shortly.)
The ability to download applets with confidence that no harm will be done and that no security will
be breached is considered by many to be the single most innovative aspect of Java.
Portability
Portability is a major aspect of the Internet because there are many different types of computers and
operating systems connected to it. If a Java program were to be run on virtually any computer
connected to the Internet, there needed to be some way to enable that program to execute on different
systems. For example, in the case of an applet, the same applet must be able to be downloaded and
executed by the wide variety of CPUs, operating systems, and browsers connected to the Internet. It
is not practical to have different versions of the applet for different computers. The same code must
work on all computers. Therefore, some means of generating portable executable code was needed.
As you will soon see, the same mechanism that helps ensure security also helps create portability.
Java’s Magic: The Bytecode
The key that allows Java to solve both the security and the portability problems just described is that
the output of a Java compiler is not executable code. Rather, it is bytecode. Bytecode is a highly
optimized set of instructions designed to be executed by the Java run-time system, which is called
the Java Virtual Machine (JVM). In essence, the original JVM was designed as an interpreter for
bytecode. This may come as a bit of a surprise since many modern languages are designed to be
compiled into executable code because of performance concerns. However, the fact that a Java
program is executed by the JVM helps solve the major problems associated with web-based
programs. Here is why.
Translating a Java program into bytecode makes it much easier to run a program in a wide
variety of environments because only the JVM needs to be implemented for each platform. Once the
run-time package exists for a given system, any Java program can run on it. Remember, although the
details of the JVM will differ from platform to platform, all understand the same Java bytecode. If a
Java program were compiled to native code, then different versions of the same program would have
to exist for each type of CPU connected to the Internet. This is, of course, not a feasible solution.
Thus, the execution of bytecode by the JVM is the easiest way to create truly portable programs.
Chapter 1
The History and Evolution of Java
15
The fact that a Java program is executed by the JVM also helps to make it secure.
Because the JVM is in control, it can contain the program and prevent it from generating
16
PART I
The Java Language
side effects outside of the system. As you will see, safety is also enhanced by certain restrictions that
exist in the Java language.
In general, when a program is compiled to an intermediate form and then interpreted by a virtual
machine, it runs slower than it would run if compiled to executable code. However, with Java, the
differential between the two is not so great. Because bytecode has been highly optimized, the use of
bytecode enables the JVM to execute programs much faster than you might expect.
Although Java was designed as an interpreted language, there is nothing about Java that prevents
on-the-fly compilation of bytecode into native code in order to boost performance. For this reason,
the HotSpot technology was introduced not long after Java’s initial release. HotSpot provides a JustIn-Time (JIT) compiler for bytecode. When a JIT compiler is part of the JVM, selected portions of
bytecode are compiled into executable code in real time, on a piece-by-piece, demand basis. It is
important to understand that it is not practical to compile an entire Java program into executable code
all at once, because Java performs various run-time checks that can be done only at run time. Instead,
a JIT compiler compiles code as it is needed, during execution. Furthermore, not all sequences of
bytecode are compiled—only those that will benefit from compilation. The remaining code is simply
interpreted. However, the just-in-time approach still yields a significant performance boost. Even
when dynamic compilation is applied to bytecode, the portability and safety features still apply,
because the JVM is still in charge of the execution environment.
Servlets: Java on the Server Side
As useful as applets can be, they are just one half of the client/server equation. Not long after the
initial release of Java, it became obvious that Java would also be useful on the server side. The result
was the servlet. A servlet is a small program that executes on the server. Just as applets dynamically
extend the functionality of a web browser, servlets dynamically extend the functionality of a web
server. Thus, with the advent of the servlet, Java spanned both sides of the client/server connection.
Servlets are used to create dynamically generated content that is then served to the client. For
example, an online store might use a servlet to look up the price for an item in a database. The price
information is then used to dynamically generate a web page that is sent to the browser. Although
dynamically generated content is available through mechanisms such as CGI (Common Gateway
Interface), the servlet offers several advantages, including increased performance.
Because servlets (like all Java programs) are compiled into bytecode and executed by the JVM,
they are highly portable. Thus, the same servlet can be used in a variety of different server
environments. The only requirements are that the server support the JVM and a servlet container.
The Java Buzzwords
No discussion of Java’s history is complete without a look at the Java buzzwords. Although the
fundamental forces that necessitated the invention of Java are portability and security, other factors
also played an important role in molding the final form of the language. The key considerations were
summed up by the Java team in the following list of buzzwords:
• Simple
17
PART I
• Secure
The Java Language
Chapter 1
The History and Evolution of Java
18
Portable
• Object-oriented
• Robust
• Multithreaded
• Architecture-neutral
• Interpreted
• High performance
• Distributed
• Dynamic
Two of these buzzwords have already been discussed: secure and portable. Let’s examine what
each of the others implies.
Simple
Java was designed to be easy for the professional programmer to learn and use effectively.
Assuming that you have some programming experience, you will not find Java hard to master. If you
already understand the basic concepts of object-oriented programming, learning Java will be even
easier. Best of all, if you are an experienced C++ programmer, moving to Java will require very little
effort. Because Java inherits the C/C++ syntax and many of the objectoriented features of C++, most
programmers have little trouble learning Java.
Object-Oriented
Although influenced by its predecessors, Java was not designed to be source-code compatible with
any other language. This allowed the Java team the freedom to design with a blank slate. One
outcome of this was a clean, usable, pragmatic approach to objects. Borrowing liberally from many
seminal object-software environments of the last few decades, Java manages to strike a balance
between the purist’s “everything is an object” paradigm and the pragmatist’s “stay out of my way”
model. The object model in Java is simple and easy to extend, while primitive types, such as
integers, are kept as high-performance nonobjects.
Robust
The multiplatformed environment of the Web places extraordinary demands on a program,
because the program must execute reliably in a variety of systems. Thus, the ability to create
robust programs was given a high priority in the design of Java. To gain reliability, Java restricts
you in a few key areas to force you to find your mistakes early in program development. At the
same time, Java frees you from having to worry about many of the most common causes of
programming errors. Because Java is a strictly typed language, it checks your code at compile
time. However, it also checks your code at run time. Many hard-to-track-down bugs that often turn
up in hard-to-reproduce run-time situations are simply impossible to create in Java. Knowing that
Chapter 1
The History and Evolution of Java
what you have written will behave in a predictable way under diverse conditions is a key feature
of Java.
To better understand how Java is robust, consider two of the main reasons for program failure:
memory management mistakes and mishandled exceptional conditions (that is, run-time errors).
Memory management can be a difficult, tedious task in traditional
19
20
PART I
The Java Language
programming environments. For example, in C/C++, the programmer must manually allocate and
free all dynamic memory. This sometimes leads to problems, because programmers will either forget
to free memory that has been previously allocated or, worse, try to free some memory that another
part of their code is still using. Java virtually eliminates these problems by managing memory
allocation and deallocation for you. (In fact, deallocation is completely automatic, because Java
provides garbage collection for unused objects.) Exceptional conditions in traditional environments
often arise in situations such as division by zero or “file not found,” and they must be managed with
clumsy and hard-to-read constructs. Java helps in this area by providing object-oriented exception
handling. In a well-written Java program, all run-time errors can—and should—be managed by your
program.
Multithreaded
Java was designed to meet the real-world requirement of creating interactive, networked programs.
To accomplish this, Java supports multithreaded programming, which allows you to write programs
that do many things simultaneously. The Java run-time system comes with an elegant yet
sophisticated solution for multiprocess synchronization that enables you to construct smoothly
running interactive systems. Java’s easy-to-use approach to multithreading allows you to think about
the specific behavior of your program, not the multitasking subsystem.
Architecture-Neutral
A central issue for the Java designers was that of code longevity and portability. At the time of
Java’s creation, one of the main problems facing programmers was that no guarantee existed that if
you wrote a program today, it would run tomorrow—even on the same machine. Operating system
upgrades, processor upgrades, and changes in core system resources can all combine to make a
program malfunction. The Java designers made several hard decisions in the Java language and the
Java Virtual Machine in an attempt to alter this situation. Their goal was “write once; run anywhere,
any time, forever.” To a great extent, this goal was accomplished.
Interpreted and High Performance
As described earlier, Java enables the creation of cross-platform programs by compiling into an
intermediate representation called Java bytecode. This code can be executed on any system that
implements the Java Virtual Machine. Most previous attempts at cross-platform solutions have done
so at the expense of performance. As explained earlier, the Java bytecode was carefully designed so
that it would be easy to translate directly into native machine code for very high performance by
using a just-in-time compiler. Java run-time systems that provide this feature lose none of the
benefits of the platform-independent code.
21
PART I
The Java Language
Distributed
Java is designed for the distributed environment of the Internet because it handles TCP/IP protocols.
In fact, accessing a resource using a URL is not much different from accessing a file. Java also
supports Remote Method Invocation (RMI). This feature enables a program to invoke methods across
a network.
Chapter 1
The History and Evolution of Java
22
Dynamic
Java programs carry with them substantial amounts of run-time type information that is used to
verify and resolve accesses to objects at run time. This makes it possible to dynamically link code in
a safe and expedient manner. This is crucial to the robustness of the Java environment, in which
small fragments of bytecode may be dynamically updated on a running system.
The Evolution of Java
The initial release of Java was nothing short of revolutionary, but it did not mark the end of Java’s
era of rapid innovation. Unlike most other software systems that usually settle into a pattern of small,
incremental improvements, Java continued to evolve at an explosive pace. Soon after the release of
Java 1.0, the designers of Java had already created Java 1.1. The features added by Java 1.1 were
more significant and substantial than the increase in the minor revision number would have you
think. Java 1.1 added many new library elements, redefined the way events are handled, and
reconfigured many features of the 1.0 library. It also deprecated (rendered obsolete) several features
originally defined by Java 1.0. Thus, Java 1.1 both added to and subtracted from attributes of its
original specification.
The next major release of Java was Java 2, where the “2” indicates “second generation.” The
creation of Java 2 was a watershed event, marking the beginning of Java’s “modern age.” The first
release of Java 2 carried the version number 1.2. It may seem odd that the first release of Java 2 used
the 1.2 version number. The reason is that it originally referred to the internal version number of the
Java libraries, but then was generalized to refer to the entire release. With Java 2, Sun repackaged the
Java product as J2SE (Java 2 Platform Standard Edition), and the version numbers began to be
applied to that product.
Java 2 added support for a number of new features, such as Swing and the Collections Framework,
and it enhanced the Java Virtual Machine and various programming tools. Java 2 also contained a few
deprecations. The most important affected the Thread class in which the methods suspend( ), resume(
), and stop( ) were deprecated.
J2SE 1.3 was the first major upgrade to the original Java 2 release. For the most part, it added
to existing functionality and “tightened up” the development environment. In general, programs
written for version 1.2 and those written for version 1.3 are source-code compatible. Although
version 1.3 contained a smaller set of changes than the preceding three major releases, it was
nevertheless important.
The release of J2SE 1.4 further enhanced Java. This release contained several important
upgrades, enhancements, and additions. For example, it added the new keyword assert, chained
exceptions, and a channel-based I/O subsystem. It also made changes to the Collections Framework
and the networking classes. In addition, numerous small changes were made throughout. Despite the
significant number of new features, version 1.4 maintained nearly 100 percent source-code
compatibility with prior versions.
The next release of Java was J2SE 5, and it was revolutionary. Unlike most of the previous Java
upgrades, which offered important, but measured improvements, J2SE 5 fundamentally expanded the
Chapter 1
The History and Evolution of Java
scope, power, and range of the language. To grasp the magnitude of the changes that J2SE 5 made to
Java, consider the following list of its major new features:
• Generics• Annotations
23
24
PART I
The Java Language
• Autoboxing and auto-unboxing
• Enumerations
• Enhanced, for-each style for loop
• Variable-length arguments (varargs)
• Static import
• Formatted I/O
• Concurrency utilities
This is not a list of minor tweaks or incremental upgrades. Each item in the list represented a
significant addition to the Java language. Some, such as generics, the enhanced for, and varargs,
introduced new syntax elements. Others, such as autoboxing and auto-unboxing, altered the
semantics of the language. Annotations added an entirely new dimension to programming. In all
cases, the impact of these additions went beyond their direct effects.
They changed the very character of Java itself.
The importance of these new features is reflected in the use of the version number “5.” The next
version number for Java would normally have been 1.5. However, the new features were so
significant that a shift from 1.4 to 1.5 just didn’t seem to express the magnitude of the change.
Instead, Sun elected to increase the version number to 5 as a way of emphasizing that a major event
was taking place. Thus, it was named J2SE 5, and the Developer’s Kit was called JDK 5. However,
in order to maintain consistency, Sun decided to use 1.5 as its internal version number, which is also
referred to as the developer version number. The “5” in J2SE 5 is called the product version number.
The next release of Java was called Java SE 6. Sun once again decided to change the name of the
Java platform. First, notice that the “2” was dropped. Thus, the platform was now named Java SE,
and the official product name was Java Platform, Standard Edition 6. The Java Developer’s Kit was
called JDK 6. As with J2SE 5, the 6 in Java SE 6 is the product version number. The internal,
developer version number is 1.6.
Java SE 6 built on the base of J2SE 5, adding incremental improvements. Java SE 6 added no
major features to the Java language proper, but it did enhance the API libraries, added several new
packages, and offered improvements to the runtime. It also went through several updates during its
(in Java terms) long life cycle, with several upgrades added along the way. In general, Java SE 6
served to further solidify the advances made by J2SE 5.
Java SE 7
The newest release of Java is called Java SE 7, with the Java Developer’s Kit being called JDK 7,
and an internal version number of 1.7. Java SE 7 is the first major release of Java since Sun
Microsystems was acquired by Oracle (a process that began in April 2009 and that was completed in
January 2010). Java SE 7 contains many new features, including significant additions to the language
and the API libraries. Upgrades to the Java run-time system that support non-Java languages are also
included, but it is the language and library additions that are of most interest to Java programmers.
Chapter 1
The History and Evolution of Java
25
The new language features were developed as part of Project Coin. The purpose of Project Coin
was to identify a number of small changes to the Java language that would be incorporated into JDK
7. Although these new features are collectively referred to as “small,” the effects of these changes are
quite large in terms of the code they impact. In fact, for many programmers, these changes may well
be the most important new features in Java SE 7. Here is a list of the new language features:
• A String can now control a switch statement.
• Binary integer literals.
• Underscores in numeric literals.
• An expanded try statement, called try-with-resources, that supports automatic resource
management. (For example, streams can now be closed automatically when they are no
longer needed.)
• Type inference (via the diamond operator) when constructing a generic instance.
• Enhanced exception handling in which two or more exceptions can be caught by a single
catch (multi-catch) and better type checking for exceptions that are rethrown.
• Although not a syntax change, the compiler warnings associated with some types of varargs
methods have been improved, and you have more control over the warnings.
As you can see, even though the Project Coin features were considered small changes to the
language, their benefits will be much larger than the qualifier “small” would suggest. In particular,
the try-with-resources statement will profoundly affect the way that stream-based code is written.
Also, the ability to now use a String to control a switch statement is a long-desired improvement
that will simplify coding in many situations.
Java SE 7 makes several additions to the Java API library. Two of the most important are the
enhancements to the NIO Framework and the addition of the Fork/Join Framework. NIO (which
originally stood for New I/O) was added to Java in version 1.4. However, the changes proposed for
Java SE 7 fundamentally expand its capabilities. So significant are the changes, that the term NIO.2
is often used.
The Fork/Join Framework provides important support for parallel programming. Parallel
programming is the name commonly given to the techniques that make effective use of computers
that contain more than one processor, including multicore systems. The advantage that multicore
environments offer is the prospect of significantly increased program performance. The Fork/Join
Framework addresses parallel programming by
• Simplifying the creation and use of tasks that can execute concurrently
• Automatically making use of multiple processors
Therefore, by using the Fork/Join Framework, you can easily create scaleable applications that
automatically take advantage of the processors available in the execution environment. Of course,
not all algorithms lend themselves to parallelization, but for those that do, a significant improvement
in execution speed can be obtained.
Chapter 1
The History and Evolution of Java
26
The material in this book has been updated to reflect Java SE 7, with many new features, updates, and
additions indicated throughout.
A Culture of Innovation
Since the beginning, Java has been at the center of a culture of innovation. Its original release redefined
programming for the Internet. The Java Virtual Machine (JVM) and bytecode changed the way we think about
security and portability. The applet (and then the servlet) made the Web come alive. The Java Community
Process (JCP) redefined the way that new ideas are assimilated into the language. Because Java is used for
Android programming, Java is part of the smartphone revolution. The world of Java has never stood still for
very long.
Java SE 7 is the latest release in Java’s ongoing, dynamic history.
Name:
Description:
…