Java in a Nutshell

Java in a Nutshell, 8th Edition

Benjamin J. Evans, Jason Clark, David Flanagan
English

Overview

It’s a great time to be a Java developer—Java performance continues to improve, and Java 17 is the fastest release yet.

Download Java in a Nutshell, the reference guide every Java developer needs at their fingertips. This book is designed to help you get the most out of versions through Java 17, with examples that show how to take advantage of modern Java APIs and development best practices.

  • Get up to speed on language and core library details through Java 17
  • Learn Java’s syntax and model for object-oriented programming
  • Explore generics, enumerations, annotations, and lambda expressions
  • Examine how concurrency and memory are intertwined
  • Delve into Java’s latest I/O APIs, including asynchronous channels
  • Become familiar with development tools in OpenJDK

Excerpt

In this section, we’ll discuss some of the most frequently asked questions about Java and the lifecycle of programs written in the Java environment.

What is a virtual machine?

When developers are first introduced to the concept of a virtual machine, they sometimes think of it as “a computer inside a computer” or “a computer simulated in software.” It’s then easy to imagine bytecode as “machine code for the CPU of the internal computer” or “machine code for a made-up processor.” However, this simple intuition can be misleading.

What is bytecode?

In fact, JVM bytecode is actually not very similar to machine code that would run on a real hardware processor. Instead, computer scientists would call bytecode a type of intermediate representation—a halfway house between source code and machine code.

Is javac a compiler?

Compilers usually produce machine code, but javac produces bytecode, which is not that similar to machine code. However, class files are a bit like object files (like Windows .dll files, or Unix .so files)—and they are certainly not human-readable. In theoretical computer science terms, javac is most similar to the front half of a compiler—it creates the intermediate representation that can then be used later to produce (emit) machine code. However, because creation of class files is a separate build-time step that resembles compilation in C/C++, many developers consider running javac to be compilation. In this book, we will use the terms “source code compiler” or "javac compiler” to mean the production of class files by javac. We will reserve “compilation” as a standalone term to mean JIT compilation—as it’s JIT compilation that actually produces machine code.

Why is it called “bytecode”?

The instruction code (opcode) is just a single byte (some operations also have parameters that follow them in the bytestream), so there are only 256 possible instructions. In practice, some are unused—about 200 are in use, but some of them aren’t emitted by recent versions of javac.

Is bytecode optimized?

In the early days of the platform, javac produced heavily optimized bytecode. This turned out to be a mistake. With the advent of JIT compilation, the important methods are going to be compiled to very fast machine code. It’s therefore very important to make the job of the JIT compiler easier—as there are much bigger gains available from JIT compilation than there are from optimizing bytecode, which will still have to be interpreted.

Is bytecode really machine independent? What about things like endianness?

The format of bytecode is always the same, regardless of what type of machine it was created on. This includes the byte ordering (sometimes called “endianness”) of the machine. For readers who are interested in the details, bytecode is always big-endian.

Is Java an interpreted language?

The JVM is basically an interpreter (with JIT compilation to give it a big performance boost). However, most interpreted languages directly interpret programs from source form (usually by constructing an abstract syntax tree from the input source file). The JVM interpreter, on the other hand, requires class files—which, of course, require a separate source code compilation step with javac. In fact, the modern version of many languages that were traditionally interpreted (such as PHP, Ruby, and Python) now also have JIT compilers, so the divide between “interpreted” and “compiled” languages is increasingly blurred. Once again, Java’s design decisions have been validated by their adoption in other programming environments.

Can other languages run on the JVM?

Yes. The JVM can run any valid class file, so this means that non-Java languages can run on the JVM in several ways. First, they could have a source code compiler (similar to javac) that produces class files, which would run on the JVM just like Java code (this is the approach taken by languages like Kotlin and Scala). Alternatively, a non-Java language could implement an interpreter and runtime in Java and then interpret the source form of their language directly. This second option is the approach taken by languages like JRuby (but JRuby has a very sophisticated runtime that is capable of secondary JIT compilation in some circumstances).

Related E-books