Published:
July 2, 2008
By Richard G. Baldwin
Homeschool Programming Notes # Hs00310
This tutorial lesson is part of a continuing series that is designed specifically for teaching computer programming to homeschool students and their parents. Even though the series is designed for homeschool students, everyone is welcome to use the lessons to learn computer programming.
You will learn about primitive variables, reference variables, and literal values in this lesson. Also, I will illustrate the use of primitive variables and literals using a Java application that is designed to be compiled and executed from the command line, and I will illustrate reference variables using a Greenfoot scenario. Note, however, that either approach could be used equally well for either program.
I recommend that you open another copy of this document in a separate browser window and use the following links to easily find and view the figures and listings while you are reading about them.
I recommend that you also study the other lessons in my extensive collection of online programming tutorials. You will find a consolidated index at www.DickBaldwin.com.
Without saying so at the time, I gave you a glimpse into variables when I introduced you to the use of memory in an earlier lesson. I described how chunks of memory are set aside to store data, and how those chunks of memory are given names. I told you that from that point forward, the chunk of memory could be accessed by its name for the purpose of either retrieving a copy of what is stored there, or storing something new there.
Two ways...
There are at least two ways to think about variables:
In the conceptual view, a variable can be thought of as being analogous to one of the terms in an algebraic formula or expression.
An example
For example, if you work as a manager of a retail store, you might think in terms of the relationship between the cost and the price of a product shown in Figure 1.
Figure 1. Relationship between the cost and the price of a product.
price = cost + markup |
Think of the terms as variables
If you were to write a computer program that evaluates this expression, you would probably consider price, cost, and markup all to be variables.
Every variable in Java has a name and a value. The value may be a default value if some other value has not yet been purposely stored in the variable.
Case sensitivity
The name of a variable is case sensitive. In other words, the name avariable is not the same as the name aVariable.
Value may change
The value of a variable may change as the program executes. (That's why it's called a variable and not a constant.)
Once again, what is a variable?
Conceptually, we might say that a variable in a computer program is the stored instance of a type whose value can change (vary) as the program executes. (See What do we mean by Type in Resources.)
Use names to access values
The instances have names like price, cost, and markup. We think of those names as the names of the variables. The names of the variables give us easy access to the values contained in the variables. Thus, a variable is a named pigeonhole in memory where we can store data for later retrieval and use.
Some operations cause the value of a variable to change while other operations simply access the value without changing it.
Evaluating the expression
The evaluation of the expression shown in Figure 1 by a computer program might go something like the following:
At the risk of confusing you, if price had an initial value of 0, cost had an initial value of 2.00 and markup had an initial value of 1.50, and if we could see the evaluation taking place in incremental steps, we might see something that looks like Figure 2.
Figure 2. Stages in the evaluation of an expression.
price = cost + markup price = cost + 1.50 price = 2.00 + 1.50 3.50 = 2.00 + 1.50 |
We would end up with price having a value of 3.50. If this diagram helps, that's good. If it is confusing, just forget it.
Only the value of price is modified
In the above expression, only the value of the variable named price is modified. The values of cost and markup are not modified by evaluating the expression.
The physical view takes us back to the description (in a previous lesson) of how memory is used in a computer program.
In the physical view, a variable is the chunk of memory that has a name, and into which a value can be stored. The name of the chunk of memory is the name of the variable. The value stored in the chunk of memory is the value of the variable.
Storing and retrieving
As the program executes, the values stored in those chunks of memory can be replaced by other values. In that way, the values of the variables can change as the program executes.
It is also possible to access the value stored in a chunk of memory without modifying it. In that way, the values of variables can be used to evaluate expressions without modifying those values.
Declaration of a variable
In Java, a variable must be declared before it can be used.
The declaration of a variable causes a chunk of memory of the correct size to be set aside and given a name.
That chunk of memory then becomes the physical manifestation of the variable.
Syntax for declaration of a variable
The syntax for declaring a variable in Java is shown in Figure 3.
Figure 3. Syntax for declaring a variable in Java.
int cost; |
In this case, cost is the name of a new variable, and int is the name of the type of the new variable.
Every variable has a type
As shown in the above declaration, every variable must have a declared type. As you learned in the earlier lesson titled What do we mean by Type? (see Resources), the type determines the range of values that can be stored in the variable (an instance of the type) and also determines the operations that can be performed on one or more variables of that type.
As a practical matter, the type also determines the required size of the chunk of memory that must be set aside to store the contents of the variable.
Specifying variable value range and operations
Thus, when you declare that a new variable will be of a specified type, you are specifying the range of values that can be stored in the variable as well as the operations that can be performed on that variable, alone or in combination with other variables.
I will present and explain two different sample programs in this lesson. I could use the command-line procedures described in the lesson titled Java Programming Overview to write, compile, and execute the programs. I could also use Greenfoot as described in the lesson titled Introduction to Methods with Greenfoot (see Resources for links to both lessons), or I could use any of several other tools to write, compile, and execute the programs. For variety, I will illustrate the first sample program using command-line procedures and will illustrate the second sample program using Greenfoot.
The purpose of the first sample program is to illustrate the use of variables in a manner similar to that described above involving price, cost, and markup.A complete listing of this sample program is provided in Listing 9 near the end of the lesson. You should be able to copy it into a source file named Var01.java and then compile and execute it. When you do, the output shown in Figure 4 should appear on your computer screen.
Figure 4. Screen output for sample program named Var01.
Remember, file names in Java are case sensitive.
I have used boldface text to emphasize certain aspects of the code.
Declare three variables
The code fragment shown in Listing 1 declares three variables of type double.
Listing 1. Declaration of three variables of type double.
double price; double cost; double markup; |
You will recall from the earlier lesson on types that the double type makes it possible for us to work with values having fractional parts. In this case, the variables are conceptually intended to represent dollars and cents. Therefore, they must be capable of storing values with fractional parts.
Memory has now been set aside and named
Once the three statements in Listing 1 have been executed, three chunks of memory have been set aside with the names price, cost, and markup. Each of the chunks is of sufficient size to contain a value of the type double.
Assign some values
The fragment shown in Listing 2 establishes a value for each of the variables named cost and markup.
Listing 2. Assign values to two of the variables.
//Put values in cost and markup cost = 2.00; markup = 1.50; |
The kinds of statements used here are typically referred to as assignment statements, meaning that values are being assigned to the variables.
The assignment operator
The equal sign (=), when used in this context, is usually referred to as the assignment operator. I will have a lot more to say about operators in a future lesson.
Each of the statements in Listing 2 causes the (literal) value shown to be stored in the chunk of memory having the name of the variable. (I will have more to say about literal values later in this lesson.)
Retrieve and use the values
The fragment in Listing 3 retrieves copies of the values stored in the two chunks of memory (variables) named cost and markup. It adds those two values together, and then stores (assigns) the result to the chunk of memory (variable) named price.
Listing 3. Retrieve and use the values stored in the variables.
//Calculate price price = cost + markup; |
Display the results
Finally, the fragment in Listing 4 retrieves a copy of the value, which has now been stored in the chunk of memory (variable) named price. That copy is passed as a parameter to the method named println.
Listing 4. Display the value stored in the variable named price.
//Display price System.out.println(price); |
When the variable is used in the manner shown in Listing 4, the behavior of the program is to cause the value to be retrieved from the variable, passed as a parameter to the method named println, and displayed on the computer screen as shown in Figure 4. Hence, execution of this program causes the value 3.5 to be displayed on the computer screen.
As you learned in an earlier lesson (see Resources), the primitive Java types are:
Primitive types, primitive variables
A variable whose declared type is one of the primitive types is commonly called a primitive variable. All others are commonly called reference variables.
Primitive variables are old stuff
Primitive variables have been around since the beginning of computer programming, and there is nothing special about them. The variables in the sample program discussed earlier were all primitive variables. Primitive variables behave pretty much as described in the discussion of that program in most programming languages.
In particular, whenever the name of a primitive variable is used in an expression, the name is replaced by the value of the variable, and that value is then used in an attempt to evaluate the expression.
Let's party!
The children are having a birthday party. The mother tells the children to go look in the mailbox for a bag of candy. When they get there, they don't find a bag of candy. Rather, they find a note telling them to go look in the pantry for a bag of candy. When they get to the pantry, they find another note telling them to go look on the porch for a bag of candy. When they get to the porch, they finally find the bag of candy.
Indirection
This is called indirection because the children made their way to the bag of candy via an indirect route instead of a direct route.
Objects and references
Extending the analogy to computer programming, a reference variable doesn't contain a bag of candy. In fact, it doesn't contain anything having any intrinsic value. Rather, it simply contains a note telling us where the bag of candy is stored, somewhere else in memory.
In this crude analogy, we would refer to the bag of candy as an object, and we would refer to the contents of the reference variable as a reference.
Very briefly, what is an object?
I will have a lot more to say about objects in a future lesson. For the time being, let me explain it like this. As you learned in an earlier lesson on types, when you define a class, you are actually creating a new type. You can think of the class definition as a blueprint or a plan from which objects can be constructed.
An instance of a plan
Recall from the earlier lesson that I told you that if you build three model airplanes from the same set of plans, you are creating three instances of the plans. That is what we mean when we use the word instance in Java.
An instance of a class
An object is an instance of a class. The object occupies a chunk of memory similar to a variable (but it is probably a lot more complex than the chunk occupied by a variable).
|
Objects don't have names in Java
However, the chunk of memory occupied by an object does not have a simple name, as is the case with a variable. Rather, it has an address and its location is known by its address. A complex form of that address is available to us, and is commonly called a reference.
Cannot access an object by its name
Since objects don't have names, we cannot access them by name. Rather, we use a special syntax to cause the object to come into existence and to cause the object's reference to be stored in a named reference variable. Then we access the object by calling out the name of the reference variable. In other words, we use the name of a reference variable to access the object to which it refers.
A complete listing of this sample program is provided in Listing 10 near the end of the lesson. To create this scenario in Greenfoot, you begin by opening the Greenfoot IDE and creating a new scenario named Var02. Open the context menu on the World class and create a new subclass named Var02. Open the editor on the subclass named Var02 and paste the code from Listing 10 into the editor, replacing all of the skeleton code currently in the editor. Then compile the scenario. This should cause the IDE to look similar to Figure 5, except that it will be wider. (I manually reduced the width of the IDE to force it to force it to fit in this narrow publication format.)
Figure 5. Greenfoot IDE for scenario named Var02.
|
If you click either the Act button or the Run button on the Greenfoot IDE at that point, a Greenfoot Terminal Window should appear on the screen showing the current date and time in a format similar to that shown in Figure 6.
Figure 6. Screen output from Greenfoot scenario named Var02.
|
If you click one of the buttons again, the date and time will appear on a new line in the terminal window. Each time you click one of the two buttons, the act method in the scenario will execute once producing one line of output text in the terminal window. To clear the terminal window, select Clear on the Options menu on the terminal window.
I used boldface text in this presentation to emphasize certain aspects of the code. (However, your actual code should never contain boldface, or anything other than plain text.)
A class named Date
The Java standard class library contains a class definition for a class named Date. Since this class is already available, we don't have to define it. Rather, we can use it to create an object, which is an instance of the class.
Jargon
At this point, I am going to hit you with some jargon. Because we say that an object is an instance of a class, somewhere along the way, someone turned the word instance into a verb. Now it is very common for Java programmers to say that they are going to "instantiate an object" of a particular class. By this, they mean that they are going to create an instance of a particular class.
Declare a reference variable
The statement in Listing 5 declares a variable whose name is refVar and whose type is Date.
Listing 5. Declare a reference variable of the type Date.
Date refVar; |
Not a primitive variable
Because the specified type (Date) is not one of the eight primitive types, we know that the variable declared in Listing 5 is a reference variable instead of a primitive variable.
Once declared, this reference variable is suitable for storing a reference to an object instantiated from the class named Date.
Instantiate a Date object
The statement in Listing 6 instantiates an object from the class named Date. It also assigns the object's reference to the reference variable named refVar that was declared in Listing 5. From that point forward, unless some other reference is assigned to the variable, the variable can be used to access the object instantiated in Listing 6.
Listing 6. Create and save the reference to a Date object.
refVar = new Date(); |
Note the syntax
Note in particular the special syntax used to instantiate the object. The syntax involves the use of the word new in conjunction with the name of the class from which the object is to be instantiated.
(There's actually a lot more to it than that, but let's be satisfied with that brief explanation for the time being. I will have much more to say about the details of this operation in a future lesson.)
Display object's contents
The statement in Listing 7 passes a copy of the contents of the reference variable to the method named println.
Listing 7. Display the contents of the Date object.
System.out.println(refVar); |
The code in the println method uses the reference to find the Date object in memory. Then it requests and gets access to the data stored in the object. Having access to the data stored in the object, the println method then causes that data to be displayed in a Greenfoot terminal window as shown in Figure 6.
(There is also much more to this than meets the eye, but lets be satisfied with that simple explanation for the time being.)
The important point ...
The important point here is that refVar is not the object. Rather, refVar is the name of a variable that contains a reference to the object. That reference is analogous to the note that the children found in the mailbox telling them to go look in the pantry for the bag of candy.
Go find the object
When the println method receives a copy of this reference variable, it uses the reference stored in that variable to find the object in memory. After it finds the object, it extracts and displays the date and time information that has been stored in the object.
One more analogy - the drain cleaner
Because the concept of indirection is so important, I am going to describe one more analogy in an attempt to solidify the concept in your mind. Consider the following scenario.
A house is an object
Miss Jones lives in a house. Consider the house to be analogous to an object. In her house is a kitchen sink. Consider the sink to be analogous to some data stored in the object.
Registering a reference to the object
Unfortunately, her sink is stopped up. She calls the company that cleans sink drains and requests service. In the process, she registers the address of her house with the customer service dispatcher.
The dispatcher is the reference variable
The process of registering her address with the dispatcher is roughly analogous to assigning the reference to her house (the object) to a reference variable (the dispatcher).
Joe calls the dispatcher
Joe is the company service technician. After he completes his current service call, he makes a call to the dispatcher (the reference variable). He obtains the address (reference) of Miss Jones's house (object) from the dispatcher.
Using the reference to find the object
He uses the reference to find the object (the house). When he locates the house (the object) he knocks on the door and asks Miss Jones for access to the sink (the data). Assuming that he is able to present the right credentials, Miss Jones gives him access to the sink and he does the job.
Where does data originate?
The data used by a program can originate from a variety of sources. For example, data can be entered from the keyboard; data can be read from a disk file; data can be downloaded from a web site, etc.
Data can be coded into the program
Data can also be coded into the program when the program is written. In this case, we would call it a literal or a literal value.
For example, the code fragment in Listing 8 declares a variable named pi and then assigns a literal numeric value to that variable.
Listing 8. A literal numeric value.
double pi; pi = 3.14159; |
Do you recognize this value?
While you may recognize this as the value of the numeric constant named pi, which is commonly used for doing calculations with circles, literals don't have to be famous values. A literal can be any value. For example, a literal could be an overhead rate or a telephone number.
Do some calculations with circles
Having executed the two statements in Listing 8, we could then use the value stored in the variable named pi to perform arithmetic such as calculating the area of a circle.
(Actually, the value of pi is already defined in the standard math library, but it makes a pretty good example for explanation of literals anyway.)
A value coded into the program...
This is just about all there is to understanding literals. There are some special rules that come into play in certain situations, and I will discuss those rules at the appropriate points in time. For now, just remember that a literal is a value that is coded into the program when the program is written.
By the way...
Some literal values were coded into the program named Var01 that is presented in Listing 9. See if you can identify them.
I encourage you to copy the code from Listing 9 into your source code editor. Compile the code, and execute it at the command line. Experiment with the code, making changes, and observing the results of your changes. Make certain that you can explain why your changes behave as they do.
I also invite you to use Greenfoot to replicate the scenario shown in Listing 10. Once again, experiment with the code, making changes and observing the results of your changes. Make certain that you can explain why your changes behave as they do.
Use Greenfoot to create a scenario named MyName01 that will store your name in a variable of type String and then display your name in a Greenfoot Terminal Window when you click either the Act button or the Run button in the Greenfoot IDE.
Hint: String values in Java are surrounded by quotation marks as in "Dick Baldwin".
Export the scenario as an application and execute it from the command line. Then export it as an applet and load it into a browser (locally) to execute it. (See Introduction to Methods with Greenfoot in Resources for information on exporting Greenfoot scenarios.)
You learned about primitive variables, reference variables, and literal values in this lesson. I illustrated the use of primitive variables and literals using a simple Java application designed to be compiled and executed from the command line. I illustrated reference variables using a Greenfoot scenario.
The next lesson will provide a view of classes from 30,000 feet. Future lessons will fill in many of the details that will be omitted from that lesson.
Listing 9. Source code for program named Var01.
class Var01 { public static void main(String[] args){ //Declare three double variables double price; double cost; double markup; //Put values in cost and markup cost = 2.00; markup = 1.50; //Calculate price price = cost + markup; //Display price System.out.println(price); }//end main }//End Var01 class |
Listing 10. Source code for the Greenfoot scenario named Var02.
import greenfoot.*; import java.util.Date; /********************************************************* * Scenario Var02. * Illustrates reference variables. ********************************************************/ public class Var02 extends World{ public Var02(){//constructor // Create a new world consisting of a single cell // with one pixel on each side. super(1,1,1); }//end constructor public void act(){ //Declare a reference variable of the type Date Date refVar; //Create a Date object and store its reference in // the reference variable. refVar = new Date(); //Display contents of the Date obj System.out.println(refVar); Greenfoot.stopSimulation(); }//end method act }//end class |
Copyright 2008, Richard G. Baldwin. Reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.
Richard has participated in numerous consulting projects and he frequently provides onsite training at the high-tech companies located in and around Austin, Texas. He is the author of Baldwin's Programming Tutorials, which have gained a worldwide following among experienced and aspiring programmers. He has also published articles in JavaPro magazine.
In addition to his programming expertise, Richard has many years of practical experience in Digital Signal Processing (DSP). His first job after he earned his Bachelor's degree was doing DSP in the Seismic Research Department of Texas Instruments. (TI is still a world leader in DSP.) In the following years, he applied his programming and DSP expertise to other interesting areas including sonar and underwater acoustics.
Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.
-end-