So, you want to program in Java? That's great, and you've come to the right place. The Java 101 series
provides a self-guided introduction to Java programming, starting with
the basics and covering all the core concepts you need to know to become
a productive Java developer. This series is technical, with plenty of
code examples to help you grasp the concepts as we go along. I will
assume that you already have some programming experience, just not in
Java.
This inaugural article introduces the Java platform and explains the
difference between its three editions: Java SE, Java EE, and Java ME.
You'll also learn about the role of the Java virtual machine (JVM) in
deploying Java applications. I'll help you set up a Java Development Kit
(JDK) on your system so that you can develop and run Java programs, and
I'll get you started with the architecture of a typical Java
application. Finally, you'll follow step-by-step instructions to compile
and run a simple Java app.
What is Java?
You can think of Java as a general-purpose, object-oriented language
that looks a lot like C and C++, but which is easier to use and lets you
create more robust programs. Unfortunately, this definition doesn't
give you much insight into Java. A more detailed definition from Sun
Microsystems is as relevant today as it was in 2000:
Let's consider each of these definitions separately:
Java is a simple language. Java was initially modeled
after C and C++, minus some potentially confusing features. Pointers,
multiple implementation inheritance, and operator overloading are some
C/C++ features that are not part of Java. A feature not mandated in
C/C++, but essential to Java, is a garbage-collection facility that
automatically reclaims objects and arrays.
Java is an object-oriented language. Java's
object-oriented focus lets developers work on adapting Java to solve a
problem, rather than forcing us to manipulate the problem to meet
language constraints. This is different from a structured language like
C. For example, whereas Java lets you focus on savings account objects, C
requires you to think separately about savings account state (such a balance) and behaviors (such as deposit and withdrawal).
Java is a network-savvy language. Java's extensive
network library makes it easy to cope with Transmission Control
Protocol/Internet Protocol (TCP/IP) network protocols like HTTP
(HyperText Transfer Protocol) and FTP (File Transfer Protocol), and
simplifies the task of making network connections. Furthermore, Java
programs can access objects across a TCP/IP network, via Uniform
Resource Locators (URLs), with the same ease as you would have accessing
them from the local file system.
Java is an interpreted language. At runtime, a Java
program indirectly executes on the underlying platform (like Windows or
Linux) via a virtual machine (which is a software representation of a
hypothetical platform) and the associated execution environment. The
virtual machine translates the Java program's bytecodes (instructions
and associated data) to platform-specific instructions through
interpretation. Interpretation is the act of figuring out what a
bytecode instruction means and then choosing equivalent "canned"
platform-specific instructions to execute. The virtual machine then
executes those platform-specific instructions. Interpretation makes
it easier to debug faulty Java programs because more compile-time
information is available at runtime. Interpretation also makes it
possible to delay the link step between the pieces of a Java program
until runtime, which speeds up development.
Java is a robust language. Java programs must be
reliable because they are used in both consumer and mission-critical
applications, ranging from Blu-ray players to vehicle-navigation or
air-control systems. Language features that help make Java robust
include declarations, duplicate type checking at compile time and
runtime (to prevent version mismatch problems), true arrays with
automatic bounds checking, and the omission of pointers. (We will
discuss all of these features in detail later in this series.)
Another aspect of Java's robustness is that loops must be controlled by
Boolean expressions instead of integer expressions where 0 is false and a
nonzero value is true. For example, Java doesn't allow a C-style loop
such as while (x) x++; because the loop might not end where expected. Instead, you must explicitly provide a Boolean expression, such as while (x != 10) x++; (which means the loop will run until x equals 10).
Java is a secure language. Java programs are used in
networked/distributed environments. Because Java programs can migrate to
and execute on a network's various platforms, it's important to
safeguard these platforms from malicious code that might spread viruses,
steal credit card information, or perform other malicious acts. Java
language features that support robustness (like the omission of
pointers) work with security features such as the Java sandbox security
model and public-key encryption. Together these features prevent viruses
and other dangerous code from wreaking havoc on an unsuspecting
platform. In theory, Java is secure. In practice, various security vulnerabilities have been detected and exploited. As a result, Sun Microsystems then and Oracle now continue to release security updates.
Java is an architecture-neutral language. Networks
connect platforms with different architectures based on various
microprocessors and operating systems. You cannot expect Java to
generate platform-specific instructions and have these instructions
"understood" by all kinds of platforms that are part of a network.
Instead, Java generates platform-independent bytecode instructions that
are easy for each platform to interpret (via its implementation of the
JVM).
Java is a portable language. Architecture neutrality
contributes to portability. However, there is more to Java's portability
than platform-independent bytecode instructions. Consider that integer
type sizes must not vary. For example, the 32-bit integer type must
always be signed and occupy 32 bits, regardless of where the 32-bit
integer is processed (e.g., a platform with 16-bit registers, a platform
with 32-bit registers, or a platform with 64-bit registers). Java's
libraries also contribute to portability. Where necessary, they provide
types that connect Java code with platform-specific capabilities in the
most portable manner possible.
Java is a high-performance language. Interpretation
yields a level of performance that is usually more than adequate. For
very high-performance application scenarios Java uses just-in-time
compilation, which analyzes interpreted bytecode instruction sequences
and compiles frequently interpreted instruction sequences to
platform-specific instructions. Subsequent attempts to interpret these
bytecode instruction sequences result in the execution of equivalent
platform-specific instructions, resulting in a performance boost.
Java is a multithreaded language. To improve the performance of programs that must accomplish several tasks at once, Java supports the concept of threaded execution.
For example, a program that manages a Graphical User Interface (GUI)
while waiting for input from a network connection uses another thread to
perform the wait instead of using the default GUI thread for both
tasks. This keeps the GUI responsive. Java's synchronization primitives
allow threads to safely communicate data between themselves without
corrupting the data. (See threaded programming in Java discussed elsewhere in the Java 101 series.)
Java is a dynamic language. Because interconnections
between program code and libraries happen dynamically at runtime, it
isn't necessary to explicitly link them. As a result, when a program or
one of its libraries evolves (for instance, for a bug fix or performance
improvement), a developer only needs to distribute the updated program
or library. Although dynamic behavior results in less code to distribute
when a version change occurs, this distribution policy can also lead to
version conflicts. For example, a developer removes a class type from a
library, or renames it. When a company distributes the updated library,
existing programs that depend on the class type will fail. To greatly
reduce this problem, Java supports an interface type, which is like a contract between two parties. (See interfaces, types, and other object-oriented language features discussed elsewhere in the Java 101 series.)
Unpacking this definition teaches us a lot about Java. Most importantly,
it reveals that Java is both a language and a platform. I'll have more
to say about Java platform components -- namely the Java virtual machine
and Java execution environment -- later in this article.
Three editions of Java
Sun Microsystems released the Java 1.0 software development kit (JDK) in
1995. The first JDK was used to develop desktop applications and
applets, and Java subsequently evolved to encompass enterprise-server
and mobile-device programming. Storing all of the necessary libraries in
a single JDK would have made the JDK too large to distribute,
especially because distribution in the 1990s was limited by small-size
CDs and slow network speeds. Since most developers didn't need every
last API (a desktop application developer would hardly need to access
enterprise Java APIs), Sun solved the distribution issue by factoring
Java into three main editions. These eventually became known as Java SE,
Java EE, and Java ME:
Java Platform, Standard Edition (Java SE) is the Java platform for developing client-side applications, which run on desktops, and applets, which run in web browsers.
Java Platform, Enterprise Edition (Java EE) is the Java
platform built on top of Java SE, which is used exclusively to develop
enterprise-oriented server applications. Server-side applications
include servlets, which are Java programs that are similar to
applets but run on a server rather than a client. Servlets conform to
the Java EE Servlet API.
Java Platform, Micro Edition (Java ME) is also built on top of Java SE. It is the Java platform for developing MIDlets, which are Java programs that run on mobile information devices, and Xlets, which are Java programs that run on embedded devices.
Java SE is the foundation platform for Java and is the focus for this
series. Code examples will be based on the most recent version of Java
at the time of writing, which is currently Java SE 8 update 45.
Overview of the Java platform
Java is both a programming language and a platform for running compiled
Java code. This platform consists mainly of the JVM, but also includes
an execution environment that supports the JVM's execution on the
underlying (native) platform. The JVM includes several components for
loading, verifying, and executing Java code. Figure 1 shows how a Java
program executes on this platform.
At the top of the diagram is a series of program class files, and one of
these class files is denoted as the main class file. A Java program
consists of at least the main class file, which is the first class file
to be loaded, verified, and executed.
The JVM delegates class loading to its classloader component.
Classloaders load class files from various sources, such as file
systems, networks, and archive files. They insulate the JVM from the
intricacies of class loading.
A loaded class file is stored in memory and represented as an object created from the Class
class. Once loaded, the bytecode verifier verifies the various bytecode
instructions to ensure that they are valid and won't compromise
security.
Comments
Post a Comment