As we know, a Java program is a collection of interacting objects, where each object encapsulates a portion of the program’s attributes and actions. Objects belong to classes, which serve as templates or blueprints for creating objects.
Think again of the cookie cutter analogy. Just as a cookie cutter is used to shape and create individual cookies, a class definition is used to shape and create individual objects.
Programming in Java is primarily a matter of designing and defining class definitions, which are then used to construct objects. The objects perform the program’s desired actions.
To push the cookie cutter analogy a little further, designing and defining a class is like building the cookie cutter. Obviously, very few of us would bake cookies if we first had to design and build the cookie cutters. We’d be better off using a pre-built cookie cutter. By the same token, rather than designing our own classes, it will be easier to get into “baking” programs if we begin by using some predefined Java classes.
The Java library contains many pre-defined classes that we will use in our programs. So let’s begin our study of programming by using two of these classes, the String and Graphics classes.
Subsection2.2.1Creating and Combining Strings
Strings are very useful objects in Java and in all computer programs. They are used for inputting and outputting all types of data. Therefore, it essential that we learn how to create and use String objects.
Figure 2.2.1 provides an overview of a very small part of Java’s String class. In addition to the two String() constructor methods, which are used to create strings, it lists several useful instance methods that can be used to manipulate strings.
The String class also has two instance variables: value, which contains the string’s characters, such as “Hello98”, and count, which records the number of characters in the string.
Recall from Chapter 1 that in order to get things done in a program we send messages to objects, which is a matter of calling one of its instance methods. In effect, we use an object’s methods to get the object to perform certain actions for us.
For example, if we have a String, named str and we want to find out how many characters it contains, we can call its length() method, using the expression str.length(). If we want to print its length, we can embed this expression in a print statement:
In general, to use an object’s instance method, we refer to the method in dot notation by first naming the object and then the method:
The objectName refers to a particular object, and the methodName() refers to one of its instance methods.
Because instance methods belong to objects, to use one of the String methods in a program, we must first create a String object. To create a String object, we first declare a String variable.
String str; // Declare a String variable named str
We then create a String object by using the new keyword in conjunction with one of the String() constructors and assign the new object to the variable we declared:
str = new String("Hello"); // Create a String containing the word "hello"
This example will create a String that contains, as its value, the word "Hello" that is passed in by the constructor. The String object that this creates is shown in Figure 2.2.2.
We can also use a constructor with an empty parameter list. And note that we can combine the variable declaration and the object creation into one statement:
String str2 = new String(); // Create a String
This example will create a String object that contains the empty string as its value. The empty string has the literal value "" — that is, a pair of double quotes that contain no characters. Because the empty string has no characters, the count variable stores a zero (Figure 2.2.3).
Try running the program below.
Run the following code. Add another string that is the empty string and print out its length.
To summarize, in Java, we must use the keyword new and a constructor to assign an initial value to a String variable — or to any other type of object variable.
This differs from how we assign an initial value to variables of primitive type, such as int and boolean variables. Because primitive types are not objects in Java, we can assign them values with a simple assignment statement:
int num = 5;
This difference relates to the way Java treats these two types of variables in the computer’s memory. A variable of a primitive type is a name for the memory locations where a value of that type is stored.
By contrast, a String variable (and a variable for any other type of object) stores a reference to an object of that type. (A reference is also called a pointer because it points to the memory address where the object itself is stored.) The object’s constructor creates an object of that type somewhere in memory and supplies a reference to it that is stored in the variable. Figure 2.2.4 illustrates this difference with a simple example.
The main reason for this difference is that primitive types have a fixed size. But objects do not. An int in Java is always 32 bits. But a String or a Riddle object can vary in size.
There is another important difference between primitive and object variables. As soon as a primitive variable is declared, it is assigned a default value of the appropriate type. For example, the default value for an int variable is \(0\) and the default value for a boolean variable is false.
By contrast, if an object variable is declared, and not assigned an object, its default value is null, which indicates that it points to nothing. It has no object to point to (Figure 2.2.5).
Once you have constructed a String object, you can use any of the methods shown in Figure 2.2.1 on it. One of the most useful String method is the concat(String) method, which can be used to concatenate two strings. This method takes a String argument. And it returns a String that combines a String argument to the String that the method is called on. For example:
String s1 = new String("George ");
String s2 = new String("Washington");
In this case, the concat() method adds the Strings2 to the end of the Strings1. The result will be the String"George Washington".
Because strings are so important, Java allows a number of shortcuts to be used when creating and concatenating strings. For example, you don’t have to use new String() when creating a new string object. The following code will also work:
String s1 = "George ";
String s2 = "Washington";
Similarly, an easier way to concatenate two String objects is to use the plus sign (+), which serves as a concatenation operator in Java:
System.out.println(s1 + s2);
Another useful String method is the equals() method. This is a boolean method, which is used to compare two String objects. If both have the same characters, in the same order, it will return true. Otherwise it will return false. For example, consider the following code segment:
will not only not print out true, it will cause the program to crash — to terminate abnormally.
It is an error to use the method of a String variable, or any other object variable whose value is null. When the above code is executed, it will report a null pointer exception, one of the most common runtime errors. When you see that error message, it means that you were trying to use a null — one that does not refer to any object.
On the other hand, the empty string is a perfectly good String object which just happens to contain zero characters.
Figure 2.2.6 shows a program that uses string concatenation to create some silly sentences. The programs declares a number of string variables, named s, s1, and so on, and it instantiates a String object for each variable to refer to. It then prints out a top-five list using the concatenation operator to combine strings. Can you figure out what it prints without running it?
Try running the program below.
Run the following code. Click on the "Show Code Lens" button and then the Next button to step through the code.
When the following Java code fragment is executed, the output would be:
String s = "ing";
System.out.println("s" + s + s + " k" + s + ".");