(Updated August 23, 2024)
Table of Contents
-
About the Second Edition
A Brief History of Java
Translating the Language
An Example
A Word on Programming Methodologies
A Proposed Template
Quiz
Exercises
About the Second Edition
This textbook has undergone a significant renovation in 2024.
Replit is no longer embedded within chapters since they changed their embed/deploy/pricing model. As a result, there is now a button for every complete program that allows you to launch a separate pop-up window that sends you to the Replit site where the code is housed.
From there, you can fork the project and make it your own. Enhancing the baseline examples is part of the joy of this design. As we take something known and change it, we begin to learn new ideas and deepen our understanding.
That said, it’s a great idea to create a Replit account at Replit.com. Be sure you are logged in to Replit when perusing the code. This will provide the best overall experience.
We’ve also changed the source code colorization engine from Prism.JS to Highlight.JS with a modified atom-one-dark theme. While some functionality has been lost (line numbers, block highlighting), the author feels this provides a less cluttered view. This, coupled with moving to the Source Code Pro font with plenty of padding within the text, makes for a more effortless reading experience.
Every effort has been made to make this free online book fully accessible. We use the WAVE Web Accessibility Evaluation Tool to test every chapter for compliance.
For example, you can view the current report for this chapter.
A Brief History of Java
Java was created in 1991 by James Gosling, Mike Sheridan, and Patrick Naughton. Originally named Greentalk, then Oak, it finally became Java around 1995.
The first JDK (Java Development Kit) was introduced in 1996. Similar to the JRE (Java Runtime Environment), the JDK allows users to create and develop new software using the Java compiler.
There have been many versions of Java, with various features being added, deprecated, replaced, or removed at each iteration.
A small table of general release dates and major details is listed below:
Java Version | Release Year | Some Major Details of Release |
---|---|---|
JDK 1.0 | 1996 | First stable release |
JDK 1.1 | 1997 | JDBC, Unicode, JavaBeans |
J2SE 1.2 | 1998 | (There was split to J2SE and J2EE) Swing, Collections |
J2SE 1.3 | 2000 | HotSpot JVM, JNDI |
J2SE 1.4 | 2002 | Regex, XML & XSLT, JCE/JSSE/JAAS |
J2SE 5.0 | 2004 | (Major!) Scanner, printf, enumerations, autoboxing/autounboxing |
Java SE 6 | 2006 | Scripting support, JDBC 4.0, likely the buggiest version released |
Java SE 7 | 2011 | String added to switch, JavaFX as up Update 6. |
Java SE 8 (LTS) | 2014 | Date/time API, Lambda expressions, Launch JavaFX apps |
Java SE 9 | 2017 | Tight integration with JavaFX |
Java SE 10 | 2018 | var reserved word for local variable type inference. JavaFX to be removed from 11! |
Java SE 11 (LTS) | 2018 | Epsilon GC, HTTP client, Unicode 10, TLS1.3 support, JavaFX removed |
Java SE 12 | 2019 | switch as statement and expression (preview) |
Java SE 13 | 2019 | Unicode 12.1, Text Blocks (Preview), Reimplement Legacy Socket API |
Java SE 14 | 2020 | Simplified switch expressions, instanceof pattern matching, packaging tool |
Java SE 15 | 2020 | Unicode 13, Text Blocks |
Java SE 16 | 2021 | Mostly a bug-fix release |
Java SE 17 (LTS) | 2021 | Sealed classes, pattern matching for switch (preview), enhanced PRNGs |
Java SE 18 | 2022 | UTF8 by default, jwebserver introduced, pattern matching for switch (second preview) |
Java SE 19 | 2022 | Unicode 14.0, methods to create preallocated HashMap s and HashSet s, pattern matching for switch (third preview), record patterns (preview), virtual threads (preview) |
Java SE 20 | 2023 | Unicode 15.0, pattern matching for switch (fourth preview) record patterns (second preview), virtual threads (second preview) |
Java SE 21 (LTS) | 2023 | virtual threads, sequenced collections, record patterns, pattern matching for switch , String templates (preview) |
Translating the Language
The Java language operates a little differently than most programming languages. Languages like C, C++, and COBOL are translated languages. Java is also a translated language. What is different about them is how these other languages are translated.
Each computer has its hardware: CPU, memory, disk, and other peripheral and removable devices. The general term for this is a platform. The platform often includes the operating system amidst this cast of characters.
The CPU is typically the one component for which languages are translated. That is to say that your program is converted, using a compiler, from the human consumable form of source code to another computer consumable form known as object code. Object code means that the code is intended to run on a specific platform object. This object code is then linked with system libraries and other such glues to produce what we often call executables or libraries. You may have seen them as filename.EXE or libname.DLL in Windows or libblah.a and libxyz.so in Linux. All of these are forms of executables. Some can be invoked directly from the command line or a graphical user interface (GUI), while others may need further arrangements or connective tissue within the system.
At this point, you might say, “Well, this means that whatever program I create can only run on the platform for which it was compiled,” which is quite correct. The key term is platform. If you write a program to run in the Linux operating system running on an Intel processor, then the platform is “Linux on Intel.” Suppose you write a GUI for the Windows operating system running on an Intel processor. In that case, the platform is “Windows on Intel.” The programs can run on any other physical computer if it uses the same platform. Certainly, this is not perfectly true as other circumstances often break this concept. For example, a program written for Windows 10 likely will not run on Windows 8 or Windows 7. This is a paradox that indicates that the past is unable to see the future; it is quite likely that the Windows 10 application is taking advantage of capabilities that did not exist in Windows 7 or 8. So, even though they are all Windows operating systems, one has to build the program to the least common denominator to have an opportunity to run on all versions of Windows. The application should use libraries and tools available on all versions – which can be done but may not be simple.
Enter Java. Java is a compiled language. We write source code, and the compiler produces object code. However, this object code is special, so special that we do not call it object code. Instead it is called bytecode and is stored in the class file. Bytecode is an intermediate language executed in the Java Virtual Machine (JVM). The Java Virtual Machine or JVM is the component that runs the bytecode program. The JVM consists roughly of a bytecode interpreter and the Just In Time (JIT) compiler. The JIT is used to improve the program speed through optimizations and compiling to machine code for a given hardware platform. The diagram in Figure 1 provides a rough outline of creating a Java program.
Figure 1: Turning source code into a program and producing output.
With this added complexity comes the beauty that Java programs are platform independent. We can compile the program once and then take the class file to any computer running the same or newer version of Java.
An example
So, how does this all work? It is quite simple. Take a look at the Java program in Example 1.
public class FirstJavaProgram {
public static void main(String[] args) {
System.out.println("Woohoo! My first program!");
}
}
Example 1: Simple Java Program.
This program identifies a class named FirstJavaProgram
. There is a single method named main()
and this method contains one statement that is used for output. In general, Java programs are made up of classes and these classes have one or more methods that employ statements to perform the work for which the program was constructed.
Using an editor (vi, emacs, gedit, TextPad, notepad) or integrated development environment (DrJava, Eclipse), the program is keyed in and saved as a file named FirstJavaProgram.java
. The Java language requires the filename to match the public class line exactly and have the .java
extension. This file is known as our source code. It is time to turn this source code into an executable program.
Figure 2 shows an active CodeRunner session where the source code is entered and saved. The user then selected the Run button. The program’s output appears in the pane at the bottom of the window.
The following screenshots show various IDEs (Integrated Development Environments) from which to choose. There are many, and each serves a particular purpose to the application writer or developer.
The following two screenshots show that you do not even need an IDE to get the job done. However, you will quickly notice a lack of visual guidance that the other interfaces provide. The previous examples of colorized code established a hierarchy of file structure and even pre-compiled the code so that you would see errors before compiling the entire project.
Figure 5: Using an editor like vi.
Figure 6: Compiling and running the Java program on the command line.
It would be theoretically possible for you to take the class file to any other system with the Java Runtime Environment (JRE) installed, which means it is time to mention the difference between JDK and JRE. The Java compiler and the tools necessary for application development are available in the JDK. The JRE enables a platform to launch Java class files created using a JDK. These two worlds are separate. This also means that if you develop an application on Java 7 JDK and the platform, you plan to run this program on only has Java 6 JRE, you could run into some trouble when moving your class file around. So this is still not a perfect system, but it is an improvement over having to compile for every platform. Figure 7 shows the relationship between JDK, JRE, JVM, and JIT.
Figure 7: Relationships of all the Java development and runtime components.
A Word on Programming Methodologies
There are two standard approaches (paradigms) to program design which are the procedural (a subset of the structured paradigm) and object-oriented approaches. (There is also a third paradigm called functional. Although way beyond this discussion, it is worth noting that it exists.)
The procedural programming approach seeks to break a significant problem or goal into smaller sub-problems or sub-goals. These individual parts of the whole will grapple with solving small pieces of the problem while keeping an eye on the greater purpose of reassembling the pieces into the final solution. The data and the code that operates on the data are kept separate and independent throughout this process. Languages such as C, COBOL, BASIC, Pascal, and FORTRAN have used this methodology for decades.
The object-oriented programming approach seeks to close the gap between code and data by intentionally merging the data with the methods that manipulate or manage the data. We develop classes that are blueprints for objects that contain both the data and code. The goal is to create objects that model real-world objects with their characteristics represented in the data and their behaviors defined in code. Writing Java programs using object-oriented design (OOD) achieves this. Therefore Java is an object-oriented programming (OOP) language since it implements the concepts of OOD.
You will learn how to think about data and the actions that need to be performed on this data in a whole new way. As a result, you will begin to develop a new appreciation for problem-solving related to program design and implementation in an object-oriented world.
A Proposed Template
As you progress to writing your own Java programs, it is beneficial to consider a template whereby you know how to begin. We will introduce the first By Design concept. We need to write programs and have a way to run them. We have already discussed using an IDE, so you will need to acquire one and stick with it.
After selecting an IDE, we need the means to work on projects. To that end, Example 2 is a roughed template for building basic Java programs that will serve you well throughout this book.
//import java.util.Scanner;
public class ProgramTemplate {
//static Scanner kb = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("My program has begun!");
// Java statements go here!
System.out.println("My program is ending!");
}
}
Example 2: Simple Java Program Template.
You can remove the println()
statements whenever you want. However, leaving them in for the first few programs you write can help build confidence in your understanding of how Java programs work and how they are written.
The use of Scanner
will be described in Chapters 2 and 3. For now, they are present but commented out. The forward slashes (//
) can be removed to expose the code and notify the compiler that you intend to use the Scanner
class.
Quiz
The Java Environment
Exercises
- Install Java and IntelliJ Idea or another IDE (Integrated Development Environment) and successfully run the
FirstJavaProgram.java
, above. - Research the history of Java and the differences between Oracle Java and the OpenJDK platforms.
- Research the details of the Oracle Java LTS lifecycle. Understanding supported versions of Java is essential to successful software development.