Learning Java, the cover image and related marks are trademarks of O'Reilly Media, Inc. Use of the information and instructions in this work is at your own risk.
Preface
Who Should Read This Book
As you learn about Java, you will also learn a powerful and practical approach to soft. On the surface, Java looks like C or C++, so you will have a slight advantage in using this book if you have some experience with one of these languages.
New Developments
The final part of this book is devoted to discussing Java in the context of web application.
Using This Book
If you're already a programmer and just need to learn Java in the next five minutes, you're probably looking for examples. If that doesn't help your boat, at least see the information in Chapter 3 that explains how to use com‐.
Online Resources
Conventions Used in This Book
Using Code Examples
O’Reilly Online Learning
How to Contact Us
We have a website for this book where we list errata and any additional information. Find us on Facebook: http://facebook.com/oreilly Follow us on Twitter: http://twitter.com/oreillymedia Watch us on YouTube: http://www.youtube.com/oreillymedia.
Acknowledgments
A Modern Language
Enter Java
Java’s Origins
In 1992, work on the project led to the formation of the Sun subsidiary FirstPerson, Inc. As it happens, these are also some of the requirements for a universal, Internet-savvy programming language.
Growing Up
Today, an offshoot of the Java platform underlies Google's Android operating system, which powers billions of phones and other mobile devices. In a somewhat rocky start to his tenure, Oracle sued Google over its use of the Java language in Android and lost.
A Virtual Machine
Once HotSpot knows which parts of the code are critical to performance, HotSpot compiles those parts into optimal native machine code. Since it only compiles a small part of the program into machine code, it can afford to take the time it takes to optimize those parts.
Java Compared with Other Languages
The problem with scripting languages is that they are rather casual about program structure and data typing. In the rest of this chapter we will give a bird's eye view of Javaland.
Safety of Design
In the rest of this chapter we will give a bird's eye view of the Java country. mate. However, in this section, we will look at some general features of the Java programming language.
Simplify, Simplify, Simplify…
The goal of Java has been to keep the language simple, provide tools that have demonstrated their utility, and let users build more complicated facilities on top of the language when needed. As you'll see in Chapter 4, Java is a fairly simple and elegant programming language, and that's still a big part of its appeal.
Type Safety and Method Binding
Java offers some of the benefits of C++ and Smalltalk; is a statically typed, late-binding language. And because Java is a late-binding language, it is possible for a subclass to override methods in its superclass, even a subclass loaded at runtime.
Incremental Development
This means that the Java compiler can perform the same kind of static type checking and usage analysis as C++. As a result, you cannot assign an object to the wrong type of variable or call nonexistent methods on an object.
Dynamic Memory Management
A reference is an atomic thing; you cannot manipulate the value of a reference except by assigning it to an object. References are passed by value, and you cannot refer to an object through more than a single level of indirection.
Error Handling
References can be used to build all the common types of data structures that a C programmer would be used to building with pointers, such as linked lists, trees, and so on. Another important difference between a reference and a pointer is that you can't play games (perform pointer arithmetic) with references to change their values; they can only point to specific methods, objects, or array elements.
Threads
The exception results in an object that contains information about the situation that caused the exception.
Scalability
This promotes error information to the same level of importance as arguments and method return types. The reuse and scaling issues are really only enforced with the module system (added again in Java 9), but that is beyond the scope of this book.
Safety of Implementation
The Java bytecode verifier is a special module and a fixed part of the Java runtime system. All these pieces must function properly to ensure security in the Java environment.
The Verifier
The ability to statically verify Java bytecode before execution allows the Java interpreter to run at full speed later with complete safety, without expensive runtime checks. A verifier is a kind of mathematical "theorem prover". It steps through the Java bytecode and applies simple, inductive rules to determine some aspect of how the bytecode will behave.
Class Loaders
To make it possible to parse the type state of the stack, Java places an additional constraint on how Java bytecode instructions are executed: all paths to the same point in the code must arrive with exactly the same type state.
Security Managers
The integrity of a security manager is based on the protection provided by the lower levels of the Java security model. Without the guarantees provided by the verifier and class loader, high-level claims about the safety of system resources are weak.
Application and User-Level Security
If the Bank of Boofa signs your checkbook application, you can verify that the application actually came from the bank and not from a fraudster and has not been tampered with. Therefore, you can tell your browser to trust applets that have Bank of Boof's signature.
A Java Road Map
Digital signatures, along with certificates, are techniques for verifying that data really comes from the source it claims to come from and that it hasn't been altered along the way.
The Past: Java 1.0–Java 11
Java 12, released in early 2019, added some minor language syntax improvements, such as a preview of switch expressions. Released in September 2019, Java 13 includes more language feature previews, such as text blocks, as well as a major reimplementation of the Sockets API.
The Present: Java 14
The ability to write programs that adapt to the language and location the user wants to use; the program automatically displays text in the appropriate language (introduced in Java 1.1). Some, such as those for working with XML and web services, are bundled with the standard edition of Java; some must be downloaded separately and deployed with your application or server.
The Future
Availability
A First Application
Java Tools and Environment
Installing the JDK
Installing OpenJDK on Linux
No matter what operating system you're using, if you're going to use OpenJDK, you'll be directed to Oracle's OpenJDK download page. 1Unless you are a more advanced *nix user and know how to manipulate your environment variables and paths.
Installing OpenJDK on macOS
The first part of the technical note covers installing the official JDK, while the last part covers installing a tar.gz archive as we showed above.
Installing OpenJDK on Windows
Here you can create a new entry for the JAVA_HOME variable and update the Path entry to know about Java. With JAVA_HOME set, you can now add an entry to the Path variable so Windows knows where to look for the java and javac tools.
Configuring IntelliJ IDEA and Creating a Project
The following chapters will go much deeper into the structure of Java programs and the commands and statements you can place in those programs. IDEA will suggest a location based on your project name and the default IDEA project folder, but you can use the ellipsis ("...") button to choose an alternative from anywhere on your computer.
Running the Project
Grabbing the Learning Java Examples
We will go into more detail about the examples and the game in upcoming chapters. As mentioned before, you can compile and run the examples from the zip file directly from the command line.
HelloJava
Now, to compile and run this source, select the ch02/HelloJava.java class from the package explorer on the left and click the Run button in the toolbar at the top. To stop the Java application in IDEA, click the red square button to the right of the green play button we used to run the program.
Classes
The main() Method
In this case, the bracketed argument tells JFrame what to display in the title bar. This is a very object-oriented concept: using an object to store text, rather than simply calling a method to "draw" the text and move on.
Classes and Objects
Variables and Class Types
Ignoring the variables used inside the main() method for the moment, only one other variable is declared in our simple HelloJava example. In this case, the main method requires that when invoked, it is passed an array of String objects in the variable called args.
HelloComponent
If you put it in the same file, you must move the new import statement to the top of the file, along with the other one. When the paintComponent() method is called, the g object is assigned a graphics object to use in the method body.
Inheritance
As for why, you'll understand when we add all sorts of new features to our new component later. Our HelloComponent class is a subclass of the JComponent class and inherits many variables and methods that are not explicitly declared in our source code.
The JComponent Class
For example, the Hypothetical Spreadsheet class can be subclassed to produce a new Scientific Spreadsheet class with extra mathematical functions and special built-in constants. In this case, the source code of the scientific spreadsheet can declare methods for the added mathematical functions and variables for the particular con‐.
Relationships and Finger-Pointing
Swing is a Java user interface toolkit, which in our case is represented by the import statement at the top; we will discuss this in more detail in Chapter 10.
Package and Imports
The package javax.swing is an example; it is part of the core API despite its name. The java.awt package contains classes of the older graphical AWT; java.net contains the network classes; and so on.
The paintComponent() Method
In this case, it is the Java window environment that calls our paintComponent() method. The specific Graphics object passed to us in the paintComponent() method corresponds to our HelloComponent area of the screen, within our frame.
HelloJava2: The Sequel
It contains methods that can be used to draw in this area and variables that represent characteristics such as cutting or drawing modes. Well, in this case, that wouldn't give much priority, and for clarity we just start over.
Instance Variables
Constructors
The HelloComponent2 constructor then does two things: it sets the text of the Message instance variable and calls addMouseMotionListener() . A method can use this to refer to the instance of the object it contains.
Events
This method is called repeatedly by the windowing system to give us updates on the mouse position. Finally, we've jumped around a few questions here: how does the system know that our class contains the necessary mouseDragged() and mouseMoved() methods (where those names come from).
The repaint() Method
Interfaces
Basically, an interface is a list of methods that a class must have; this particular interface requires our class to have methods called mouseDragged() and mouseMoved(). When you refer to an object with an interface name in this way, it means that you don't care about the actual class of the object; the only requirement-.
Goodbye and Hello Again
Tools of the Trade
JDK Environment
When in doubt, your go-to test to determine which version of the tools you're using is to use the -version flag on the java and javac: commands.
The Java VM
Running Java Applications
In this case, the JAR file includes metadata with the name of the contained startup class. A single argument to the main() method, an array of String objects, contains the command line arguments passed to the application.
System Properties
The Java interpreter continues to run until the main() method of the initial class file returns and until any threads that started it also exit. Special threads designated as daemon threads are automatically terminated when the rest of the application completes.
The Classpath
Both the Java interpreter and the Java compiler use the CLASSPATH when searching for packages and Java classes. To find other classes, the Java interpreter searches the elements of the classpath in order.
If you change the classpath and do not include the current directory, these files will no longer be accessible. If you're working within an IDE, it can remove some or all of the burden of classpath management.
Modules
You may want to pay special attention to setting and checking the classpath when you start. Ultimately, however, understanding the classpath and knowing exactly what's in it when your application is running is very important to your long-term sanity.
The Java Compiler
You can specify multiple .java files in a single javac command; the compiler creates a class file for each source file. For example, javac compares the modification times of the source and class files for all classes and recompiles them as needed.
Trying Java
Remember that if you want to use a class that is not included in the default package, you must import it. For example, any component that has already been added to our frame before we make it visible will appear immediately when we show the frame.
JAR Files
Hopefully, you'll probably make a few small mistakes as you type, correct them, and see the results, wanting to learn more. We just want to make sure you have the tools you need to continue playing through the rest of this book.
File Compression
We know this has been another whirlwind tour with several bits of code that may not make sense yet, like why CENTER is capitalized.
The jar Utility
In verbose mode, jar reports the savings achieved by compressing the files in the archive. The MANIFEST.MF file may contain a "packing list" that names the files in the archive, along with a user-definable set of attributes for each item.
The pack200 Utility
An application can get this manifest information from a JAR file using the java.util.jar.Manifest class. Note that the pack200 process completely disassembles and reconstructs your classes at the class level, so the resulting foo.jar file will not be byte-for-byte the same as the original.
Building Up
The Java runtime does not understand the pack200 format, so you cannot place archives of this type in the classpath. You can convert JARs to and from pack200 format using the pack200 and unpack200 commands provided with the JDK and OpenJDK prior to Java 14.
The Java Language
Text Encoding
Ironically, one of the scripts listed as "obso-. lete and archaic" and not currently supported by the Unicode standard is Javanese - a historical language of the people of the island of Java. may require more than 64K characters. Not all platforms that support Java support emoji output, but you can turn on jshell to find out if your environment can display emoji characters (see Figure 4-1).
Comments
It's not that you can't use or support emoji in your applications, you just need to be aware of differences in output features.
Javadoc Comments
For example, the @SuppressWarn annotation causes the compiler (and often your IDE) to suppress warnings about things like unreachable code. This note tells the compiler to perform some additional checks; these checks are intended to help you write valid code and catch bugs before you (or your users) run your program.
Variables and Constants
You can still use constants defined for classes like JLabel.CENTER above or define them in your own classes that you might type in jshell.
Types
Java code can also "reflect" or examine its types at runtime, enabling advanced types of application behavior such as inter‐. Primitive types represent simple values that have functionality built into the language; represent simple values such as num‐.
Primitive Types
In the second line of the previous example, the number 13 has a default type of int, but it is promoted to type long for assignment to the long variable. And as with integer literals, in Java 7 you can use underscore characters "_" to form floating-point numbers, but only between digits, not at the beginning, end, or next to a decimal point or the "F" marker of a number.
A child-type object can be used instead of a parent-type object. Cat items can then be used anywhere an Animal item can be used; an object of type Cat could be assigned to a variable of type Animal.
Inferring Types
Passing References
An object that implements the interface's methods can be designated by that interface type or by its own type. This adds flexibility in the type system and allows Java to go beyond the class hierarchy and create objects that actually have many types.
A Word About Strings
Generics allow user specialization of classes without changing the code of the original class. Java builds a single String object from the concatenated strings and returns it as the result of the expression.
Statements and Expressions
Statements
Note that the variable j is local to the block (visible only to the statements within it) and will not be accessible to code "after" the for loop. In the second case, a list implements the Iterable interface and can thus be the target of a for loop.
Expressions
The value of the new expression is a reference to the type of the created object. This is the same as asking if the object can be assigned to a variable of the target type.
Arrays
It is also important to note that null is not considered an instance of any class.
Array Types
Array Creation and Initialization
Allocating an array of pointers is really allocating memory for a specified number of these pointer objects. In this case, each expression must evaluate to an object that can be assigned to a variable of the base type array or null.
Using Arrays
The arraycopy() method is then used to copy the elements of names to the new array. If the target length is greater than the original array length, the new array is padded (with zeros or zeros) to the desired length.
Anonymous Arrays
Multidimensional Arrays
The syntax of the new operator allows us to leave the sizes of some dimensions undefined. The size of at least the first dimension (the most important dimension of the array) must be specified, but the sizes of any number follow.
Types and Classes and Arrays, Oh My!
Note that because the length of the array is not part of its type, the strings in the table do not necessarily have to be the same length; that is, multidimensional‐. If strings have classes, where do they fit in the class hierarchy and how are they related.
Objects in Java
Within that package, the JComponent class defines all the low-level, common properties of graphical things like frames and buttons and canvases. In our game, the Field class is where all the game pieces will be shown, but it is not a game itself.
Declaring and Instantiating Classes
We still need to create the object, using the new keyword, as shown in the second line of the previous code snippet. Although not very exciting, we can now build another class, PrintAppleDetails, which is a complete application to create an instance of Apple and print its details:.
Accessing Fields and Methods
Inside a class, we can access variables and call methods of the class directly by name. But to access the coordinates of another apple, we need to go back to point notation.
Static Members
However, since static members exist in the class itself, independent of any instance, we can also access them directly through the class. The value of EARTH_ACCEL is a constant; it can be accessed through the Apple class or its instances, but its value cannot be changed at runtime.
Local Variables
Our method has a fixed number of arguments (two); however, methods can have variable-length argument lists, allowing the method to specify that it can take any number of arguments and sort them out itself at runtime.2.
Shadowing
If we can't get to the x and y instance variables, how can we move the apple. You can use the special reference this whenever you need to refer explicitly to cur‐.
Static Methods
Here we have our trusty example of the Apple class, a1, but it is not necessary to get our list of sizes. Static methods also play an important role in various design patterns, where you limit the use of the new operator for a class to one method - a static method called a factory method.
Initializing Local Variables
We won't be writing factory methods, but you'll probably find them out in the wild, especially when you look up questions on sites like Stack Overflow. In this case, there is no chance of reaching bar in an uninitialized state, so the com‐.
Argument Passing and References
What if myMethod() also needs to change the notion of the calling method of the obj reference (i.e. make obj refer to a different object). In this code, the Element class represents one element; it contains a method to add itself to the list.
Wrappers for Primitive Types
You can construct a wrapper object from a primitive value or a string representation of a value. Each of the Number type wrappers implements the java.lang.Number interface, which allows "value" methods to access their value in all primitive forms.
Object Creation
A few more notes: constructors cannot be declared abstract, synchronized, or final (we'll define the rest of those terms later). However, constructors can be declared public, private or protected with the visibility modifiers, just like other methods, to control their accessibility.
Working with Overloaded Constructors
The syntax is limited in this way because there is a need for a clear command structure when calling constructors. There is also a point in the chain, just after calling the superclass's constructor, where the initializers of the current class's instance variables are evaluated.
Object Destruction
It's usually much easier to track down with the right tools and techniques.
Garbage Collection
Objects that live longer can be moved to other, less volatile parts of the heap. In recent implementations, the garbage collector can even "tune" itself by adjusting the size of parts of the heap based on actual application performance.
Packages
Modern Java garbage collectors effectively run continuously without forcing any long delay in the execution of the Java application. Short-lived items are placed on a special part of the heap, drastically reducing the time to recycle them.
Importing Classes
This version of the import statement tells the compiler to have every class in the package ready to use. You have another option to use external classes from other packages - you don't need to import them at all.
Custom Packages
You will see this type of input fairly often for many of the common Java packages such as AWT, Swing, Utils, and I/O. You may have checked out more of the examples in the code archive for this book.
Member Visibility and Access
Note that extending the TextArea class gives you access to the public getText() and setText() methods as well as the protected method formatText(). But MyTextDisplay (more on subclasses and extends soon in "Subclassing and Inheritance" . on page 156) does not have access to the package private variable linecount.
Compiling with Packages
Advanced Class Design
Subclassing and Inheritance
We have seen that a local variable of the same name as an instance variable shadows (hides) the instance variable. Similarly, an instance variable in a subclass can shadow an instance variable of the same name in its parent class, as shown in Figure 5-7.
Inner Classes
In Brain, we can call the method performBehavior(); that is, we can call the performBehavior() method of the Animal instance from the Brain instance. Although it is possible to construct a Brain object from elsewhere (ie from another class), Brain always requires an enclosing Animal instance to "hold" it.
Anonymous Inner Classes
The Brain class "sees" all methods and variables of the Animal class directly in its scope. The answer is that a brain object always lives in a single instance of Animal: the one it was told about when it was created.
Organizing Content and Planning for Failure
The real difference is how we organized the classes and who can access them (and the variables and methods within them). No matter how you organize members in your classes, classes in your packages, or packages in your project, you will have to deal with errors that occur.
Error Handling and Logging
2For example, the getHeight() method of the Image class returns -1 if the height is not yet known.
Exceptions
Exceptions and Error Classes
A few other packages define their own subclasses of Error, but subclasses of Error are much less common (and less useful) than subclasses of Exception. An error of this kind usually causes the Java interpreter to display a message and exit.
Exception Handling
If a previous statement fails, execution immediately jumps to the catch clause; subsequent statements are never executed. Use this "|" or syntax, we receive both types of exceptions in the same catch clause.
Bubbling Up
We've shown it here for completeness, but in general you want to be as specific as possible in the exception types you catch. The difference between catching these discrete exception types with a multiple-type catch clause and simply catching the general parent exception type is that we limit our catch to only this specific.
Stack Traces
This stack trace indicates that the main() method of the class MyApplication called the method loadFile(). Note that once the stack trace reaches Java system classes (such as FileInputStream), the line numbers may be lost.
Checked and Unchecked Exceptions
Typically, the user sees a stack trace when it is printed using the printStackTrace() method. In contrast, exceptions that are subclasses of the java.lang.RuntimeException class or the java.lang.Error class are unchecked.
Throwing Exceptions
It makes little sense to keep a reference to the Exception object we created here.). However, often you can just print the exception object itself (or toString()) to retrieve the message and stack trace.