The aim of this exercise is for you to become familiar with the different behaviours exhibited when using the
Java primitive data types and Java objects.
In this part of the exercise, you'll be expected to look at three example programs that illustrate some of the finer points of Java programming - in particular looking at the difference between Java's primitive types and Java objects.
In Java, there is a subtle difference between using the built-in, primitive data types (boolean, byte, short, char, int, long, float, double) and objects (String, Date, etc., and your own user defined classes, like Radio). In particular, the primitive data types are stored as values, while the objects are stored as references. If you are familiar with Pascal or C/C++ you can think of these references as handles or pointers to the object.
This can give rise to some odd behaviour if you're not careful. For example, take a look at the ValRef.java piece of code and answer the following questions:
You should:
Another area where you have to know the difference between having your data stored as a value or as a reference, is when you copy objects. The code in Copying.java illustrates this.
Answer the following questions (on paper, with diagrams):
You should:
Another difference between primitive values and object references occurs when you pass them as parameters to other methods. When this happens, the parameter is copied for use in the method - the code in Parameters.java tries to show this.
So:
You should:
Since primitive values aren't Java Objects, if you want to pass them as arguments to methods that take parameters of type Object - it won't work. Luckily, the clever people at JavaSoft have thought of that and provided a handy set of Object wrappers for each of the primitive types. The code in Wrapping.java illustrates this process.
So:
You should:
In this part of the exercise you will build a simple reverse polish (or postfix) calculator. That is, one that accepts arithmetic expressions like 23 + 4 in the form 23 4 +.
You are given the following piece of pseudocode that describes an algorithm for evaluating a postfix arithmetic expression:
WHILE more symbols in expression DO symbol <- next symbol IF symbol is an operand THEN push symbol onto stack ELSE (symbol is an operator) op1 <- pop stack op2 <- pop stack value <- result of applying symbol to op1 and op2 push value onto stack ENDIF ENDWHILE result <- pop stack
Your program should should ask the user for a valid postfix expression and then evaluate it and print out the result.
What method would you use with String objects if you only wanted to compare whether two strings had the same letters in them, and not whether they were in the same case (upper or lower). i.e. so that "fred" would equal "FRED"?
To copy objects you either have to make a new one and copy the values, or use the clone() method if it is implemented. Unfortunately our Radio class isn't currently cloneable - but we can change that...
Replace line 9 in the Radio.java file:
public class Radio implements Cloneable
Insert the following at line 111 in Radio.java:
/** * Makes a copy of this Radio. * * @return a clone of this radio. * @exception java.lang.OutOfMemoryError * thrown if we run out of memory while cloning * **/ public Object clone() { Object clone = null; try { // get our superclass to do the cloning for us clone = super.clone(); } catch ( CloneNotSupportedException e ) { // ignore this, because we know we're cloneable } return clone; }
Then change line 41 of Copying.java to read:
Radio walkman = (Radio)wireless.clone();
So:
What happens if you try to assign a new Radio() to wireless2 in change(), before setting its frequency to CLASSIC_FM? Why?
Try storing doubles, floats, bytes, chars and Strings into the storage object. Note the different Object wrappers required/not required.
If your calculator doesn't already, it should allow users to enter more than one expression before quitting, perhaps by asking "Do you wish to enter another?" before exiting.