What Is Java?
What Java is and where it runs: the Java Virtual Machine, bytecode, the JDK and JRE, OpenJDK builds and licenses, and the six-monthly release cycle with long-term support versions.
What Java is
Java is a general-purpose programming language and the platform it runs on. It is one of the most used languages in business software: web back ends, banking and insurance systems, energy and telecom platforms, middleware, monitoring tools and many of the portals that service desk and operations people work with every day. A few properties shape how it feels:
- Statically typed. Every variable has a type that is fixed in the code, and the compiler checks every use of it before the program runs. See static and dynamic typing.
- Object-oriented. Code is organized in classes and other types (see Object-Oriented Concepts); since Java 8 (2014) functions can also be passed around as values, in lambdas and streams.
- Managed. A garbage collector frees memory you no longer use, so you never release memory by hand (see garbage collection).
- Portable. A compiled Java program runs unchanged on Windows, Linux and macOS, on Intel and Arm processors: the compiler produces instructions for a virtual machine, not for a particular processor.
Here is a complete Java program. It works out the average of some daily meter readings:
// Daily electricity use (kWh) of one Kestrel Energy household
void main() {
double[] readings = {11.2, 9.8, 12.5, 10.1, 13.4};
double total = 0;
for (double kwh : readings) {
total = total + kwh;
}
double average = total / readings.length;
IO.println("Days measured: " + readings.length);
IO.println("Average per day: " + String.format("%.1f", average) + " kWh");
}
Days measured: 5 Average per day: 11.4 kWh
Blocks are marked with curly braces { }, statements end
with a semicolon, // starts a comment, and
IO.println prints a line. Each variable is declared
with its type: double is a floating-point number and
double[] an array of them. The program starts in the
method main. This short form, a file with just a
void main(), is new in Java 25; most existing code uses
the longer classic form with
public static void main(String[] args) inside a class.
The next page,
The JDK, javac, java and Your First Program, explains both and shows how to run a file like this.
Because the types are known in advance, the compiler catches a whole class of mistakes before anyone runs the program. Assigning text to a number is one of them; this program never starts:
void main() {
int customersAffected = "1250";
IO.println(customersAffected);
}
Main.java:2: error: incompatible types: String cannot be converted to int
The message names the file and line (Main.java:2) and
describes the problem; below it, the compiler prints the line with a
caret ^ under the spot. In Python or JavaScript the
same mistake would only show up when that line runs, and perhaps not
at all.
A short history
Java started at Sun Microsystems in the early 1990s, in a project led by James Gosling; its first name was Oak. Sun formally introduced Java in May 1995 and released JDK 1.0 in early 1996. The slogan was "write once, run anywhere": one compiled program for every kind of computer, at a time when software usually had to be rebuilt for each operating system. Oracle bought Sun in 2010 and has led Java's development since, in the open-source OpenJDK project.
| Version | Released | What it brought (selection) |
|---|---|---|
| Java 5 | 2004 |
Generics, the enhanced for loop, autoboxing,
enums, annotations
|
| Java 8 (LTS) | Mar 2014 |
Lambdas, streams, java.time,
Optional, default methods
|
| Java 9 | 2017 | The module system, JShell |
| Java 11 (LTS) | Sep 2018 | Run a single source file directly; no more separate JRE from Oracle |
| Java 17 (LTS) | Sep 2021 | Records, text blocks, sealed classes, switch expressions |
| Java 21 (LTS) | Sep 2023 | Virtual threads, pattern matching for switch, record patterns, sequenced collections |
| Java 25 (LTS) | Sep 2025 |
Compact source files with void main(), the
IO class, module imports, flexible constructor
bodies, scoped values
|
Features usually arrive first as a preview in one or more releases, switched off unless you ask for them, and become final later. The column above names the release where a feature became final (records, for example, were final in Java 16 and are listed under the first LTS release that had them).
How Java code runs
Running a Java program takes two translation steps, one before the program runs and one while it runs.
-
The Java
compiler,
javac, reads your.javafiles, checks the types and translates every class into a.classfile containing Java bytecode: compact instructions for an imaginary processor, the same on every operating system. The class file also describes the class's fields and methods. - The Java Virtual Machine (JVM) loads the class files and runs the bytecode. It starts by interpreting it, instruction by instruction, while measuring which methods run often. Its just-in-time (JIT) compiler then translates those hot methods into machine code for the actual processor. The JVM also manages memory with its garbage collector, checks types and array bounds at run time, and turns errors into exceptions.
This design is close to that of C# and .NET (Intermediate Language plus a runtime with a JIT compiler; see How C# code runs) and different from Python's, where an interpreter reads your source code each time you run it. It has three practical effects:
-
The same
.classfiles, usually packed in a.jararchive, run on any machine with a suitable JVM. A Java application is delivered once, not once per platform. - A Java program starts more slowly than a fully compiled one and gets faster after it has run for a while ("warm-up"), because the JIT compiler optimizes what it sees being used. Long-running servers profit most.
-
A class file records which Java version compiled it. A JVM refuses
class files from a newer compiler than itself, with an
UnsupportedClassVersionError, so the runtime must be at least as new as the version the application was built for.
The JDK includes javap, which shows the bytecode in a
class file. For a tiny class Hello that prints one
line, the main method compiles to four instructions:
javac Hello.java
javap -c Hello
public static void main(java.lang.String[]);
Code:
0: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #13 // String Hello from Kestrel Energy!
5: invokevirtual #15 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
You never need to read bytecode to write Java, but it shows what the
JVM actually executes: fetch System.out, load a string,
call println, return. Many other languages compile to
the same bytecode and run on the same JVM, among them Kotlin, Scala,
Groovy and Clojure.
The JDK and the JRE
Java SE (Standard Edition) is the specification: the language, the JVM and the standard class library, as defined by the Java Community Process. Concrete software that implements it comes in two packages:
-
The
Java Development Kit
(JDK) is what you install to write Java. It contains the JVM, the
class library, the compiler
javac, the launcherjavaand tools such asjshell,jar,javadoc,jcmdandjlink. - The Java Runtime Environment (JRE) is the part needed only to run programs: the JVM and the class library, without the development tools.
Until Java 8, end users installed a separate JRE from java.com, and
browsers could run Java applets with a plug-in. Oracle stopped
shipping a separate JRE and that "deployment stack" with Java 11.
Today an application either ships its own trimmed runtime, built
with the JDK tools jlink or jpackage, or
runs on a JDK or JRE that the administrator installs from one of the
builds described below; some of them, such as Eclipse Temurin, still
offer a JRE download. The Applet API itself was removed in Java 26.
OpenJDK and its builds
OpenJDK is the open-source project in which Java itself is developed, by Oracle together with companies such as Red Hat, SAP, Amazon and Microsoft. Its code is licensed under the GNU General Public License version 2 with the Classpath Exception; the exception means your own programs do not fall under the GPL just because they run on Java.
OpenJDK publishes source code, not the installers most people use. An OpenJDK distribution is a JDK built from that source code by a vendor, tested, and patched on a schedule the vendor promises. They are functionally the same Java; they differ in support periods, platforms, packaging and license terms. The common ones:
| Build | From | Cost |
|---|---|---|
| Eclipse Temurin | Eclipse Adoptium (vendor-neutral working group) | Free |
| Amazon Corretto | Amazon | Free |
| Microsoft Build of OpenJDK | Microsoft | Free |
| Red Hat build of OpenJDK, Azul Zulu, BellSoft Liberica, SapMachine | Red Hat, Azul, BellSoft, SAP | Free downloads; paid support offered |
| Oracle OpenJDK (jdk.java.net) | Oracle | Free, but updated for six months per version only |
| Oracle JDK | Oracle | Depends on version and date; see below |
Linux distributions also package OpenJDK themselves (Debian 12, for example, offers Java 17). Every example on these pages is checked with Eclipse Temurin 25.
Oracle JDK licensing
Oracle's own build has changed license terms several times, which is why companies are careful with it. The situation as of October 2026:
- Oracle JDK 21 and later are offered under the Oracle No-Fee Terms and Conditions (NFTC): free for everyone, including commercial and production use — but only until one year after the next LTS release.
- For Oracle JDK 21 that moment has come: updates released from the October 2026 Critical Patch Update (CPU), due on 20 October 2026, are planned to be offered under the Oracle Technology Network (OTN) license instead, which allows personal and development use but not free production use. Oracle JDK 17 updates moved to the OTN license in October 2024, and Java 8 and 11 updates are OTN-licensed as well.
- Oracle JDK 25 stays under the NFTC until September 2028, one year after Java 29.
- Production use outside the NFTC needs the paid Java SE Universal Subscription. It is priced per employee of the whole organization (contractors included), not per server; Oracle's price list of 1 March 2023 starts at $15 per employee per month for small organizations.
The practical consequence: an organization running Oracle JDK 21 in production either moves to Oracle JDK 25, takes a subscription, or switches to a free OpenJDK build of the same version. Because the builds are functionally the same Java, that last switch normally needs no code changes, only a new runtime and a test run.
Releases and long-term support
Since Java 10 (2018) a new feature release appears every six months, in March and September, numbered by release: 25, 26, 27. Each vendor then publishes security and bug-fix updates every quarter, in January, April, July and October; they show up in the third number (25.0.4), and an extra update between the regular ones gets a fourth (25.0.4.1).
An LTS release (long-term support) is a feature release that vendors keep patching for years instead of months. Since Java 17, every fourth release is LTS: a new one every two years. The releases between them are supported only until the next one appears, six months later. Production systems almost always run an LTS version.
| Version | Type | Released | Free updates until (at least) |
|---|---|---|---|
| Java 29 | LTS | Planned Sep 2027 | — |
| Java 28 | Feature | Planned Mar 2027 | — |
| Java 27 | Feature | 15 Sep 2026 | Mar 2027 (Temurin) |
| Java 26 | Feature | 17 Mar 2026 | Ended Sep 2026 |
| Java 25 | LTS | 16 Sep 2025 | Sep 2031 (Temurin), Oct 2032 (Corretto), Sep 2030 (Microsoft) |
| Java 21 | LTS | Sep 2023 | Dec 2029 (Temurin), Oct 2030 (Corretto), Sep 2028 (Microsoft) |
| Java 17 | LTS | Sep 2021 | Oct 2027 (Temurin), Oct 2029 (Corretto), Sep 2027 (Microsoft) |
The table shows the vendors' published dates as of October 2026. Java 8 and 11 also still receive updates from several vendors (for Java 8 until at least December 2030 at Temurin and Corretto), which says a lot about how long Java applications live. Oracle sells paid support for its LTS versions on its own schedule, for example Java 25 Premier Support until September 2030.
A small program can check which version it is running on, and do the date arithmetic for a planning note:
void main() {
IO.println(Runtime.version().feature());
IO.println(System.getProperty("java.specification.version"));
}
25 25
void main() {
LocalDate today = LocalDate.of(2026, 10, 5);
LocalDate nextCpu = LocalDate.of(2026, 10, 20); // Critical Patch Update
LocalDate temurin25End = LocalDate.of(2031, 9, 30); // "at least" Sep 2031
IO.println("Days until the October 2026 CPU: "
+ ChronoUnit.DAYS.between(today, nextCpu));
IO.println("Years of Temurin 25 support left: "
+ ChronoUnit.YEARS.between(today, temurin25End));
}
Days until the October 2026 CPU: 15 Years of Temurin 25 support left: 4
The first program prints 25 because these pages are
checked on Java 25; on Java 27 it would print 27.
LocalDate and ChronoUnit come from the
java.time package, covered in
Files, I/O and JSON.
The class library
Every JDK comes with a large standard library: thousands of
ready-made classes for text, numbers, dates, collections, files,
networking, security and concurrency. Classes are grouped in
packages with dotted names such as java.util,
java.time and java.math, and since Java 9
packages are grouped in modules; the core ones are in the
module java.base. An import line at the
top of a file lets you write the short class name instead of the
full one (LocalDate instead of
java.time.LocalDate):
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.time.LocalDate;
import java.util.List;
import java.util.Locale;
// Numbers, text, dates and locales: all from the Java class library
void main() {
BigDecimal monthlyCost = new BigDecimal("87.456");
IO.println(monthlyCost.setScale(2, RoundingMode.HALF_UP));
List<String> regions = List.of("North", "East", "South");
IO.println(String.join(" | ", regions));
LocalDate readingDay = LocalDate.of(2026, 10, 3);
IO.println(readingDay.getDayOfWeek());
Locale dutch = Locale.forLanguageTag("nl-NL");
IO.println(NumberFormat.getCurrencyInstance(dutch).format(monthlyCost));
}
87.46 North | East | South SATURDAY € 87,46
In this short file form the whole java.base module is
imported automatically, so the import lines are optional here (the
two previous examples used LocalDate without one); in a
classic class file they are required. Note the Dutch currency
format: the euro sign, a non-breaking space, and a decimal comma.
Formatting is covered in
Strings and Text.
Beyond the JDK, hundreds of thousands of open-source libraries are published on Maven Central, the main repository for Java libraries; build tools such as Maven and Gradle download them for you (see Packages, Modules and Build Tools). Those libraries are part of your application's security, as Log4Shell showed in 2021: a critical flaw in the popular logging library Log4j 2 (CVE-2021-44228, CVSS score 10.0) put a huge number of Java systems at risk even though the JDK itself was fine. Patching Java means patching the libraries too; see Running Java in Production.
Where Java is used
- Back-end services and web applications, often with the Spring framework (Spring Boot) or on application servers such as Apache Tomcat that implement the Jakarta EE standards (the successor of Java EE). See REST APIs.
- Enterprise systems in banking, insurance, government, telecom and energy: billing, customer portals, trading and integration platforms that have run for decades.
- Infrastructure and data tools: many widely used systems, such as Apache Kafka, Elasticsearch and Jenkins, are written in Java or other JVM languages, so operations teams run JVMs even if nobody writes Java.
- Android apps are written in Kotlin or Java, though Android runs them on its own runtime rather than on a standard JVM.
- Desktop tools such as the IntelliJ IDEA and Eclipse development environments.
In the Stack Overflow Developer Survey 2025, 29.4% of all respondents said they had used Java. The TIOBE Index of September 2026, which measures search-engine popularity, put Java fourth, after Python, C and C++. Java code at work typically looks like this: a small type that describes an outage ticket, and a list of tickets processed with a stream. Records are explained in Records, Enums and Sealed Types, streams in Lambdas, Functional Interfaces and Streams.
void main() {
List<Ticket> tickets = List.of(
new Ticket("INC-20417", "North", 1250),
new Ticket("INC-20418", "East", 85),
new Ticket("INC-20421", "North", 430));
int affected = tickets.stream()
.filter(t -> t.region().equals("North"))
.mapToInt(Ticket::customers)
.sum();
IO.println(tickets.get(0));
IO.println("Customers affected in North: " + affected);
}
record Ticket(String id, String region, int customers) {}
Ticket[id=INC-20417, region=North, customers=1250] Customers affected in North: 1680
Compile-time and run-time errors
The compiler can only check what it knows while building. It knows
that "1250" is a string, so assigning it to an
int is refused, as shown at the top of this page. It
cannot know what a user will type or what a file will contain.
Converting text to a number therefore compiles fine and fails only
when the program runs with bad input; the JVM then throws an
exception:
void main() {
String fromMeterFile = "12.5 kWh"; // read at run time
IO.println("Parsing the reading...");
double reading = Double.parseDouble(fromMeterFile);
IO.println(reading);
}
Parsing the reading... Exception in thread "main" java.lang.NumberFormatException: For input string: "12.5 kWh"
"Exception in thread "main"" means nothing caught the error, so the
program stopped. The JVM then prints a
stack trace: lines starting with at that show which methods were
running, ending with at Main.main(Main.java:4), the
line in your own code. Operations people see these traces in
application logs every day. Static typing removes many errors, not
all of them;
Exceptions and Error Handling
shows how to handle the rest.