Skip to main content
Top

2020 | Book

Foundational Java

Key Elements and Practical Programming

insite
SEARCH

About this book

Java is now well-established as one of the world’s major programming languages, used in everything from desktop applications to web-hosted applications, enterprise systems and mobile devices. Java applications cover cloud-based services, the Internet of Things, self-driving cars, animation, game development, big data analysis and many more domains.

The second edition of Foundational Java: Key Elements and Practical Programming presents a detailed guide to the core features of Java – and some more recent innovations – enabling the reader to build their skills and confidence though tried-and-trusted stages, supported by exercises that reinforce the key learning points. All the most useful and commonly applied Java syntax and libraries are introduced, along with many example programs that can provide the basis for more substantial applications. Use of the Eclipse Integrated Development Environment (IDE) and the JUnit testing framework is integral to the book, ensuring maximum productivity and code quality when learning Java, although to ensure that skills are not confined to one environment the fundamentals of the Java compiler and run time are also explained. Additionally, coverage of the Ant tool will equip the reader with the skills to automatically build, test and deploy applications independent of an IDE.

Topics and features:

• Presents the most up-to-date information on Java, including Java 14

• Examines the key theme of unit testing, introducing the JUnit 5 testing framework to emphasize the importance of unit testing in modern software development

• Describes the Eclipse IDE, the most popular open source Java IDE and explains how Java can be run from the command line

• Includes coverage of the Ant build tool

• Contains numerous code examples and exercises throughout

• Provides downloadable source code, self-test questions, PowerPoint slides and other supplementary material at the website http://www.foundjava.com

This hands-on, classroom-tested textbook/reference is ideal for undergraduate students on introductory and intermediate courses on programming with Java. Professional software developers will also find this an excellent self-study guide/refresher on the topic.

Dr. David Parsons is National Postgraduate Director at The Mind Lab, Auckland, New Zealand. He has been teaching programming in both academia and industry since the 1980s and writing about it since the 1990s.

Table of Contents

Frontmatter
Chapter 1. The Java Story
Abstract
This chapter introduces Java by describing how it has become a mature and popular language that is used across the world for all kinds of applications. It explains why to program successfully in Java it is necessary to understand object-oriented concepts and then apply them to Java objects. The chapter outlines how Java’s rich syntax and wide-ranging APIs mean that it can be used for all kinds of programming, from writing a command line utility to building a distributed client-server system or a complex multithreaded real-time system. It describes the history of Java and how it has matured into a major programming language supporting many aspects of the current software industry. It concludes by discussing how, despite becoming to some extent a legacy language, Java will continue to evolve and be providing programmers with the tools for coding a host of applications in all kinds of contexts for many years to come. It also explains how Java’s influence is such that a knowledge of Java can be extremely useful in learning the new generations of languages that have followed it.
David Parsons
Chapter 2. Compiling and Running Java Programs
Abstract
This chapter outlines the basics of using the tools provided with Java to compile and run code. It describes how the source code of Java class is structured, how it can be compiled using the “javac” compiler (provided with Oracle’s Java Development Kit or the OpenJDK) and how it can be run on the Java Virtual Machine from the command prompt / terminal. It explains how Java code is put into packages, and how these packages relate to the Java classpath, which it is necessary to set for the Java runtime to locate compiled code. The chapter also describes how the same process of editing, compiling, and running code can be done much more easily using the Eclipse Integrated Development Environment (IDE), which also provides many other useful facilities such as assisting with automatic code generation and highlighting errors. It also shows how Eclipse can automatically put classes into Java modules that may contain multiple packages.
David Parsons
Chapter 3. Data Types, Arithmetic and Arrays
Abstract
This chapter covers the various data types available in Java and differentiates between primitive types, which include numbers, characters, and Boolean values, and reference types such as arrays, and how variables of these types can be declared and initialized. The Java arithmetic operators are introduced, and code examples show how they can be used in arithmetic expressions. Examples of order of precedence, promotion and type casting are used to show how important it is to be aware of the way that Java manages the relationships between different data types, and how code can be written to make explicit data type conversions to ensure that programs generate the correct results. The chapter also demonstrates how Strings (which are reference types) can be concatenated together and how arrays can be used to group together related data into a single structure that can be accessed by a zero-based index. The syntax for declaring and initializing arrays is examined, including arrays that have multiple dimensions.
David Parsons
Chapter 4. Control Structures
Abstract
This chapter describes how Java’s control structures are used for selection and iteration. It looks at various types of selection syntax, including “if” and “switch” statements, and introduces the relational and Boolean operators that are used in the conditions that control “if” statements and loops. It also introduces the ternary operator, which provides a shorthand way of writing simple selections that return a value. In the context of switch statements, it discusses the “break” keyword and compares it with the behavior of the “continue” keyword. It also shows the syntax options in the recently introduced switch expression, which unlike a switch statement can return a value and includes syntax such as the “yield” keyword (to return a value) and the “arrow” operator to invoke an expression. Examples of different kinds of loop are illustrated, including “while” loops, “do…while” loops and various configurations of “for” loop, which are particularly useful for iterating through arrays. Code examples also show how the Math class can be used for random number generation, and how an array of Strings can be passed to the “main” method of a class at runtime, either from the command prompt or via the “Run Configurations” option within Eclipse.
David Parsons
Chapter 5. Creating Objects
Abstract
This chapter begins by looking at the creation and use of some objects and methods related to String data (Strings, StringBuilders, StringBuffers and the “toString” method). This is followed by some important issues regarding the way that objects are referenced in memory when programming with Java, and the way that some operators work with objects. The Java garbage collector, which handles the removal of unwanted objects from memory, is also introduced. Again, String objects are discussed, in the context of String immutability and concatenation. The latter part of the chapter is concerned with issues of how objects from packages other than “java.lang” can be used in Java applications, by using various ways of importing classes, and being aware of modules and the role of the “module-info.java” file. The chapter concludes with a brief introduction to the Javadoc documentation that can be viewed online or downloaded and viewed in a browser (as well as being integrated into Eclipse) to provide support in Java programming.
David Parsons
Chapter 6. Creating Domain Classes
Abstract
This chapter opens with some discussion of object-oriented concepts such as information hiding and the encapsulation of state and behavior inside objects. This is followed by an illustration of how classes and their fields and methods are represented in the Unified Modeling Language (UML). Subsequent code examples show how new domain classes can be created in Java, along with their fields, methods and constructors, and how Eclipse provides automated support for some of these tasks. The overloading of the constructor method to provide ways of creating objects with different sets of arguments is also explained. Further discussion of encapsulation covers constructor chaining and the four visibility modifiers; “public”, “private”, “default” and “protected”. The chapter goes on to show how the Javadoc tool can be used to generate HTML documentation for user-created classes, either from within Eclipse or from the command line. This includes some coverage of special Javadoc tags that can be added to comment blocks to provide additional information in the generated Javadoc. The final part of the chapter explores more specific aspects of creating classes including static fields and methods, JavaBean components, reflection and the “var” keyword, which can be used with local variables to allow the compiler to infer their data types.
David Parsons
Chapter 7. Objects Working Together: Association, Aggregation and Composition
Abstract
This chapter builds on the knowledge of classes and objects developed in the preceding chapters to create larger programs based on different objects communicating with one another. It illustrates different examples of the ways that objects can work together: association, where independent objects talk to each other, aggregation, where an object is made up of other objects that can vary, and composition, a very strong form of aggregation where the component objects are fixed. In the code examples, some design decisions are made, based on the concepts and syntax covered so far in the book, that might not be optimal. These serve as discussion points for ways that these design elements could be improved. For example, it considers the case of two classes that seem to have much in common and highlights how they might be better designed to share these common characteristics. This discussion serves as the foundation for the topics of inheritance and polymorphism, covered in the following chapter, that enable classes to build upon existing classes to extend and refine their behaviors.
David Parsons
Chapter 8. Inheritance, Polymorphism and Interfaces
Abstract
This chapter explains how inheritance can be used to write closely related classes that have some fields and methods in common. In the code examples, a set of classes are organized into an inheritance hierarchy of super and sub-classes that goes beyond the default behavior of Java classes to inherit directly from class “Object”. This use of inherence is built on to demonstrate how polymorphic methods can be written that allow objects of different classes to respond differently to the same method calls. Some examples are shown of classes providing polymorphic implementations of methods inherited from the “Object” class, such as “toString”. The role of abstract classes and methods in inheritance hierarchies is demonstrated through the dynamic binding of a superclass reference to a subclass object. The “super” keyword is introduced in the context of calling the methods and constructors of a superclass, and the “@Override” annotation is used to ensure that methods correctly override those inherited from a superclass. The chapter also explains how Java interfaces can be used to provide common services across a range of implementing classes and concludes by exploring some of the enhancements to interfaces introduced with Java 8, including default methods, private methods, and lambda expressions.
David Parsons
Chapter 9. Exception Handling
Abstract
This chapter explores various aspects of exception handling in Java, including the keywords; “throws”, “try”, “catch”, “finally”, and “throw”. In order to help the reader understand how to use these keywords in code, it illustrates how the exception hierarchy divides exception types into checked exceptions, which are checked by the compiler and require code to handle them, and unchecked exceptions, where the compiler does not enforce exception handling code (though it may still be very useful to include this). The chapter explains why although the Java runtime includes many exception types, it also useful to create domain-specific subclasses of Exception to represent custom exceptions. Examples are outlined to show how such exceptions can be customized to support domain-specific business rules that may need to be enforced in an application. The chapter describes how exceptions provide a robust and flexible method for dealing with these issues. The chapter concludes with a brief example of using the Optional class, which can limit the likelihood of NullPointerExceptions being thrown by an application.
David Parsons
Chapter 10. Unit Testing with JUnit
Abstract
This chapter introduces the concept of unit testing which, as part of an overall test strategy, not only helps to improve code quality but can also help to drive the design of code. The examples in this chapter use the JUnit 5 test framework, which makes it easy to create and run unit tests that make assertions against code (in units under test) to ensure that it behaves as expected. Several different types of assertion are demonstrated in code examples, including those that deal with exception handling, timeouts and forced failures. The chapter demonstrates how JUnit is included as an Eclipse library that can be added to the build path of a project and shows how test cases can easily be created and run using the integrated graphical test runner. The chapter explains how individual test cases are created, along with the required annotations to run tests and to set up code for testing. It also introduces the creation of test suites that enable multiple test cases to be run together. Some related issues such as test-driven development, “3A” and regression testing are also discussed.
David Parsons
Chapter 11. Exploring the Java Libraries
Abstract
This chapter covers a small sample of classes from some of the packages in the Java libraries. It begins with some coverage of the Object class, and the “clone” method, before looking at some other classes in the “java.lang” package (Math, System, and the wrapper classes). This is followed by coverage of two classes from the “java.util” package (Locale and Currency). Next, the chapter introduces classes from the “java.text” package that can be used to format and parse numbers and currencies. The final package covered in this chapter is “java.time”, which provides classes for representing dates and times, as well the “java.time.format” package which contains classes for formatting the data from these objects. The chapter concludes by explaining why it is important to reuse existing library classes as much as possible and become familiar with using the Javadoc to explore the classes and methods that can avoid unnecessarily writing new code, enabling the developer to concentrate on the code that really does need to be written.
David Parsons
Chapter 12. The Collections Framework and Generics
Abstract
This chapter looks at some aspects of the Collections Framework. It begins by outlining some of the main interfaces in the framework, including Iterable, Collection, and Map, and explains how these can be used to implement object associations. It lists the general purpose classes in the Collections framework that link together high-level interfaces and specific types of implementation such as the ArrayList, which implements the List interface with an underlying array implementation, and TreeMap, which implements the SortedMap interface using a tree-based implementation. The use of generics to create type-safe collections is explained, along with ways of applying generic types within inheritance hierarchies. The chapter also describes how interfaces are used by the framework to provide common services across a range of implementing classes, and how some of these vary due to the features of the different implementations used. Code examples illustrate the differences between Collections and Maps, the various ways in which Iterators can be used to scan the contents of collections, and how unmodifiable collections can be created. Utilities such as the Collections class and the Comparator interface are demonstrated, illustrated with examples of methods such as “sort” and “shuffle” that can be applied to Collection objects. Some of the interfaces, classes, and methods from the Streams API are explored, with various examples applied to an ArrayList of domain objects.
David Parsons
Chapter 13. Input and Output Streams
Abstract
This chapter looks at a range of different types of input and output stream, handling the input and output of bytes, primitives, Strings, and objects. The examples in this chapter focus on file handling because this makes it easy to demonstrate both input and output, but the chapter also explains how there are other sources and sinks of data, for example, keyboard input and console output. Code examples show how lower level stream classes support the implementation of higher level filter streams by being passed to their constructors. Reader and Writer streams that handle text-based data are contrasted with the stream classes that handle primitive data types. Methods of the File class that allow Java code to interact with the file system are demonstrated, along with streams that can handle the input and output of objects that implement the Serializable Interface. As well as some of the main classes in the java.io package, the chapter covers the basics of the Buffers, Charsets, and Channels in the java.nio package.
David Parsons
Chapter 14. Automatic Building and Testing with Ant
Abstract
This chapter introduces Ant (“Another Neat Tool”), a build tool that can be used to automate the build and deploy process, as well as running and testing code. It begins by showing how an Ant build file (by default called “build.xml”) can be created to copy source code out of Eclipse and build it independently of the IDE, while the build scripts themselves can still be run from within Eclipse. Various aspects of an Ant build file are introduced, including properties, tasks, and targets. Several Ant targets are demonstrated in different build files, including creating and deleting files and directories, compiling Java, creating Java Archive (JAR) files, and running code. Target dependencies, which allow multiple targets to be run in a specific sequence, are also described. Further examples explain how Ant can be used to run JUnit 5 tests by including a set of required JAR files on the classpath, while demonstrating some of the options within the “junitlancher” task, which runs Junit 5 test cases. The chapter concludes by explaining how Ant can be run from the command prompt outside Eclipse.
David Parsons
Chapter 15. Java and the Database (JDBC)
Abstract
This chapter explains how to create and populate a database using the MySQL relational database management system (RDBMS). It also demonstrates how a JDBC driver enables Java code to connect to and interact with a relational database using a standard API. Code examples cover the execution of queries to create a ResultSet, and the execution of updates. They also demonstrate how PreparedStatements can be set up that can be efficiently reused for common types of interaction with the database. The level of interaction between Java and the database described in this chapter is at the very simple level of moving data in and out of the database and does not address in detail the much broader issue of object relational mapping. It therefore directs readers interested in further detail of how objects can be made persistent in a relational database to explore the Java Persistence API, which can be used with both SQL and NoSQL databases.
David Parsons
Chapter 16. Multithreading
Abstract
This chapter looks at threads, using both inheritance from the Thread class, and implementing the Runnable interface. It outlines the various states that a thread can be in during its lifetime (ready, running, non-runnable, and dead). Code examples illustrate how multiple threads can be run concurrently, and how they can be put to sleep for certain periods of time. It explains how different priorities can be assigned to separate threads, and how these threads can be made less selfish by asking them to yield to other threads. Syntax differences between inheriting from the Thread class and implementing the Runnable interface are explained. A code example of applying the Runnable interface uses graphical objects to visualize how multiple threads can operate concurrently within an inheritance hierarchy. The chapter also explains how the Object class provides some methods; “wait”, “notify”, and “notifyAll”, which enable threads to avoid concurrent access to certain parts of code, known as “monitors”, that are marked by the “synchronized” keyword. The chapter concludes with a brief introduction to the concurrent collections in the “java.util.concurrent” package.
David Parsons
Chapter 17. Building GUIs with the JFC Swing Library
Abstract
This chapter looks at various aspects of using Java to create graphical user interfaces. These include Components (objects that the user interacts with such as buttons and check boxes) and Containers (components that can contain other components such as frames and panels). Several component types are described, including labels, buttons, radio buttons, text fields, and combo boxes. Examples illustrate how these components can be configured in terms of their positions, sizes, colors, and fonts and how the look and feel of the whole application can be changed to be cross platform, native, or “motif” style. Two ways of managing the layout of components in a container are introduced; either specifying their positions manually or using automatic layout managers. The layout managers covered are the BorderLayout (the default layout manager for JFrames) the FlowLayout (the default layout manager for JPanels) and the GridLayout. Examples also show how JPanels can be used to host components, and how these panels can be added to frames.
David Parsons
Chapter 18. Event-Driven Programming
Abstract
Building on the previous chapter, which covered how to make UI components appear on the screen, this chapter explains how component events can be handled to add underlying code to the UI. It outlines the features of Java that can manage events being fired from various components and mouse actions. Various types of event and event listeners are introduced, including ActionEvents, MouseEvents, and ChangeEvents. Different ways of writing event listeners are described, namely public classes, inner classes, local inner classes, anonymous inner classes, and lambda expressions. The chapter explains how each of these approaches has its own characteristics that make it appropriate for a specific context. The GridBagLayout is used to demonstrate how flexible component layouts can be built to reduce the communication overhead of alternative approaches such as using multiple panels. Finally, the chapter looks at the importance of separating the underlying data model from the view, so that the model can be separately tested before having a UI added and can be reused independently of the user interface.
David Parsons
Chapter 19. Dialogs and Menus, Models and Views
Abstract
Following on from the coverage of Swing components and event handling in the previous two chapters, this chapter covers the basic components of a WIMP (Windows, Icons, Menus, and Pointers) interface. It begins with an explanation of how to create dialogs, which provide richer options for interacting with the user through multiple windows and shows how to integrate them into a frame-based application. The initial examples demonstrate the use of some built-in Swing dialogs, such as the JOptionPane, and then progress to creating custom dialogs based on the JDialog class. This is followed by an example of how to add menus to a Swing application, including the addition of separators, mnemonics, and keyboard accelerators. The latter part of the chapter explores the Model View Controller architecture, which is an important aspect of some of the more sophisticated Swing components. Code examples introduce the separation of model and view in two components: the JTextPane and the JTable.
David Parsons
Chapter 20. Java Web Servers and the HttpClient
Abstract
Following on from the coverage of Swing components and event handling in the previous two chapters, this chapter covers the basic components of a WIMP (Windows, Icons, Menus, and Pointers) interface. It begins with an explanation of how to create dialogs, which provide richer options for interacting with the user through multiple windows and shows how to integrate them into a frame-based application. The initial examples demonstrate the use of some built-in Swing dialogs, such as the JOptionPane, and then progress to creating custom dialogs based on the JDialog class. This is followed by an example of how to add menus to a Swing application, including the addition of separators, mnemonics, and keyboard accelerators. The latter part of the chapter explores the Model View Controller architecture, which is an important aspect of some of the more sophisticated Swing components. Code examples introduce the separation of model and view in two components: the JTextPane and the JTable.
David Parsons
Backmatter
Metadata
Title
Foundational Java
Author
Dr. David Parsons
Copyright Year
2020
Electronic ISBN
978-3-030-54518-5
Print ISBN
978-3-030-54517-8
DOI
https://doi.org/10.1007/978-3-030-54518-5

Premium Partner