Learn Programming in Java


<<Previous | ToC | Next >>

Lesson #2: Variables & Expressions (Strings)

Next we learn how to tell a computer to combine values -- that would be arithmetic when we are doing numbers, but first we'll do text -- and we will learn how the computer remembers things while a program is running. After your program stops, everything it knows is gone, except for whatever is saved in a disk file -- but we called that "output". As we shall see (but not today), input and output hide under a mask of many colors.

In programming-speak, a "variable" is a place in the computer memory that holds a number that can change value during the course of running. We did variables in Chomp, and Java is the same, only different. Everything in the computer is numbers, but it helps us to think clearly about what we are doing if we pretend that some things are not numbers, and Java helps us carry out the pretense. So the first kind of variable you will learn about doesn't look like a number at all.
 

String Data

Remember your "Hello world" message, which we enclosed inside quotes? As in English, the quotation marks surround a sequence of text characters that should be understood literally, that is, that exact sequence of characters -- letters, numerals, spaces, most anything you can type on the keyboard, if you can see it on the screen it counts as a valid character inside quotes. It's called a "string" like a string of beads or pearls in a necklace, which are constrained to be in a particular order by the thread running through them. Try a few different character strings and see what happens. Obviously, if you try to include a (double) quote mark, the computer (or rather the Java compiler) will mistake it for the end of the text string, and refuse to compile the program. Try it.

So what are we to do, if we want a quote inside the string? Programmers are an anarchistic lot, we don't want to be told "You can't do that," so the people who invented the C programming language -- and this is the same as Java, which mostly copied everything that C does, except for some of the mistakes -- chose one of the characters on your keyboard that almost never gets used in real life, the backwards slant "\" and made it magic, different from the other characters. It's called an "escape" character, because it lets you briefly escape from the usual rules for text strings when you use it. Everything else (obviously except the quote), when you use it inside a text string means just that letter or character and nothing more, but if you put a back-slant next to it on the left, then it takes on new meaning. A back-slant followed by a quote means the quote is not the end of the string, but is used as a real character in the text. Try this variation on your HelloWorld program:

System.out.println("Hello \"World\"!");


Notice the two back-slants, each immediately followed by a quote. That means that those quotes will be printed as part of the text. The final quote has no back-slant next to it, so it's the normal end of the string. Try it. What happens if you put a back-slant next to another back-slant? Try it:

System.out.println("Hello \\ World!");


The first back-slant is an escape, which tells the compiler that the next character should be taken literally as a character in the text (so it prints), just like it did with the quote. Except for certain letters, back-slant does that for almost everything, although obviously most characters don't need it.

I told you about programmers who don't want to be told "You can't do that," not even when it comes to using non-printing characters in their text strings. Take for example the tab key. As far as the keyboard is concerned, it's just another number: every key on the keyboard sends a number to the computer, and the operating system understands those numbers as letters and other characters. For example, "a" is the number 97, space is 32, and the tab key is 9. What if I want a tab in my text string? Tab usually means to move to the next field, or to insert (possibly multiple) spaces, or something non-text like that. Enter the back-slant as an escape again, but this time it tells the compiler that the letter "t" after the back-slant is  to be understood as a tab character, not a letter. Other escaped letters are "\b" for backspace, "\n" for newline, and "\r" for the return key (but most modern keyboards print the label "Enter" on that key). Mostly you don't need these control characters in your text strings, but that's how they are spelled, in case you do.

Different operating systems treat return (13) and newline (10) differently, so it's best not to try to embed them in strings for printing. Instead Java gives us a programmatic way to put a new line into the output text. We have been using println to output a single line; you could also use "print" (without the "ln") and it does not start a new line. Try it. You won't see an obvious difference unless you put two print statements in your program, then you can see them print their output on the same line. Try it:

System.out.println("Hello one...");
System.out.println("Hello two.");
as compared to:
System.out.print("Hello one...");
System.out.print("Hello two.");

Variables

All that to explain text strings, which can be much more powerful than just immediately printing. Back to our one-line program, let's modify it to print out "John sees Mary."
System.out.println("John sees Mary.");


That's so boring. Suppose we want to say Mary also sees John, but we don't want to retype the whole line. This is where variables are useful. I mentioned that a variable is a place in the computer to remember a number. A string does not look like a number, but deep down inside, that's what it is. You don't need to know that, only that if you tell Java that a value is a "String" then it knows that you can put text there. Variables are generally given names -- in Chomp you had 26 predefined variables, named with the letters of the alphabet -- and in Java variables start with a letter and can have any number of letters and digits (but no spaces, we use the underscore "_" to look like a space). We try to use names that remind us what the variable means to us people, without being so long it's a pain to type the whole name. Temporary variables might just be named by a single letter, like x. Java needs to know that the variable is a String (which is spelled with a capital letter, because Java cares about the difference. So I'm going to cut up my English sentence into three words, then print out two lines, in different order. This is more typing (or a single copy/paste ;-) all within the same white panel inside the yellow block:

String j = "John";
String m = "Mary";
System.out.print(j);
System.out.print(" sees ");
System.out.print(m);
System.out.println(".");
System.out.print(m);
System.out.print(" sees ");
System.out.print(j);
System.out.println(".");


Notice that there are no quotes around the "j" in the first print statement. We don't want to print the letter "j" but rather the contents of the variable with that name. The second time around, the variables still have the names of our people, but the English sentence is printed in a different order. But that's a lot of typing. Instead we can do it in two println's, where the value to be printed is made up by "adding" (actually concatenating, which is different) the pieces together, like this:

String j = "John";
String m = "Mary";
System.out.println(j + " sees " + m + ".");
System.out.println(m + " sees " + j + ".");


Now comes the fun part. Change only the first line, so it says

String j = "Bill";


What do you think it will do? Try it. We did not change the name of the variable, only the value in it. The rest of the program knows nothing of the value, it just prints whatever is in the variable with that name. We can change it as often as we like (in separate statements) throughout the program, just as you did in Chomp with numbers. After the first println insert a new statement,

j = "William";
The first time the variable "j" is printed (before the line we added), it has the initial value "Bill", but then the value was changed, so the second time it printed the new value.

Notice that when we changed the value, we did not repeat the word "String". The first time you mention a variable in a program, you must tell Java what type it is (in this case "String"). This is called a declaration. After that you can use the variable's current value as often as you like, as we did when printing it. You can also change the value as often as you like with what is called an assignment statement, which is a variable name followed by the equal character followed by some value to put into that variable, and ending with a semicolon, somewhat like you did in Chomp, but spelled differently. Any valid string value can be put into the variable, for example:

String j = "John";
String m = "Mary";
j = j + " sees " + m;
System.out.println(j + ".");


It is important that you do not confuse the assignment operator with the mathematical notion of equality. The third line here should be read as "calculate a new string value by concatenating to the current contents of variable j the given literal string, and then concatenate on the current value of variable m and then put the resulting string value into variable j (discarding its previous value)." You can see how this works if you want to put the second println back in:

String j = "John";
String m = "Mary";
j = j + " sees " + m;
m = m + " sees " + j;
System.out.println(j + ".");
System.out.println(m + ".");


What do you think this will print out? Try it. Remember, by the time the computer gets around to assigning a new value to m, the variable j already has the new value given to it in the previous line. This kind of timing problem happens often, and we solve it with temporary variables, in this case "x":

String j = "John", m = "Mary", x; // one declaration, three variables created, two init'd
x = j + " sees " + m;             // assign to temporary 'x'
m = m + " sees " + j;
j = x;                            // use temporary value in 'x'
System.out.println(j + ".");
System.out.println(m + ".");


You will notice that I added some comments to some of the lines. Tiny programs like this, it's easy to remember what's going on, but when you are writing an interesting program involving thousands of lines stretched over months of work, it's really easy to forget a particularly clever piece of code. Besides, if you want other people to read and admire your code, you need to explain what you did. We try to put one statement per line, but sometimes a statement is too big and must be split. Your program is easier to read if you divide it up logically and indent subsidiary parts. Look at the examples I show you, or that you see online. If you are good enough to let people look at your code (or bad enough to need help), formatting your code the way other people do encourages them to not think of you as sloppy or worse. Your code is you, so make yourself presentable. It's like brushing your hair and wearing clean clothes.

I also combined all the string declarations into one line, where each variable is separated from the next by a comma. The "String" type is specified once at the front of the line and applies to all the variables declared before the semicolon that ends the statement. In this example I could have given an initial value to "x" instead of making a separate assignment; sometimes it's convenient one way, sometimes the other; both work. You do need to be careful to give a value (either by initializing it in the declaration, or else by subsequent assignment) before you try to use the value. Unlike Chomp, it is an error to try to use the value of a variable before it has a value, and the Java compiler usually will tell you about it, but sometimes the program only behaves strangely or crashes. Java programs "crash" by stopping with an error message, but other programming languages (for example C) can crash your whole computer and require a restart. Modern operating systems usually limit the damage to the running program, but not always. Don't go there. Mostly I will tell you how to avoid it.

Next: Number Types

<<Previous | ToC | Next >>

Revised: 2020 November 13