CSIS 3701: Advanced Object-Oriented Programming
Simple Types and Objects in Java
Most Java syntax is very similar to C++ (mostly because the creators of Java were C++ programmers). In particular, Java uses the same control structures (if, else, while, for, switch, case, break, etc.) and operators (+, -, = , ==, , ||, , !=, ++, +=, etc.). The main differences are in the available data types and how they are handled.
Simple Data Types
Java has the following simple types to represent numeric values:
type / sizebyte / 8 bits
short / 16 bits
int / 32 bits
long / 64 bits
float / 32 bits
double / 64 bits
Note that these are part of the language definition itself, and not dependent on the implementation (unlike 16-bit and 32-bit integers in C). This helps make Java more portable.
Like many languages, Java also has a separate type for boolean values, for which the legal values are true and false. These are keywords in Java, and are used instead of 1 and 0 in C. For example:
boolean b;
b = true;
Characters
Like C, Java has a char to represent characters in strings, but there is a major difference in how they are implemented. In C, characters are represented in ASCII using 8 bits. In Java, characters are represented in Unicode using 16 bits. Unicode is an internationally recognized standard for not only representing Latin alphabet characters (like those in ASCII), but characters in other languages as well (such as Chinese, Hebrew, Greek, etc.). For example:
char c1, c2;
c1 = ‘a’; // ASCII characters are treated like in C
c2 = ‘\u3A78’ // Other characters are represented
// in \u syntax. This is Unicode char 3A78
//(note the hex format).
Representing characters in Unicode makes it easier to write programs that are usable world wide (a particularly important consideration for applets), but does have a couple of disadvantages:
· They take up more time and space than ASCII characters. However, since Java strings are not represented as arrays of characters (as we will see later), this is not a major problem.
· File and network I/O still work primarily in ASCII 8-bit bytes. This means that programs involving this kind of I/O often have to do a lot of translating back and forth between bytes and characters.
Type Conversion
One question that must always be considered is what happens when different types are combined in the same expressions. Java uses strong typing to combine types, only allowing compatible types to be combined. For example:
int x = ‘a’; // Compiler error.
// Cannot automatically convert
// char to int (as in C).
if (1) { … } // Compiler error.
// Must use Boolean in if statements.
In particular, Java will not allow a conversion that would result in data being lost. For example:
int x = 3.7; // Compiler error.
// Java will not automatically truncate
// float to int.
Instead, you must explicitly cast to a type that would result in a loss of data. For example:
int x = (int)3.7;
While this may seem rather silly, it does insure the integrity of computations more than a weakly-typed language like C does – you wouldn’t want to accidentally truncate numbers used in large financial applications or when landing the space shuttle, for example.
Also note that in Java decimal constants are considered to be of type double, regardless of how many digits are used. That is, in the statement x = 4.2; 4.2 is considered to be a double. This can lead to unexpected compiler errors if you attempt to use floats the way you did in C++. For example, the statement
float x = 4.2;
would give a compiler error because Java would claim that you are trying to store a double in a float. You can get around this by either 1) making x a double (not an efficient solution), 2) coercing 4.2 to a float with the statement x = (float)4.2, or by putting an “F” after the number to tell Java it is a float, x = 4.2F.
Default Values
Like Basic, Java gives all variables default values when they are first declared (this helps prevent crashes due to using initialized variables, as you often get in C++). For numeric types, the default is 0, for boolean the default is false, and for characters the default is ‘\u0000’, the “null” character.
Even though this means that you can theoretically use a variable before assigning it a value, this is still poor programming practice. The Java compiler will give you a warning if you do this.
Reference Types and Objects
Anything that is not a simple type is considered an object. We will talk more about objects later, but for now we will talk about how they are created and referenced.
Specifically, a variable of some object type is actually a reference to a location in memory (kind of like a pointer). This has very important implications for the way objects are used.
Creating Objects
In these examples we will use one of Java’s built-in visual objects, called a JButton. As with simple types, variables referring to objects must be declared:
JButton b; // b is a reference to a JButton object
That is not sufficient however, because no actual JButton object has been created yet. Instead, b currently refers to null:
b ----> null
In fact, if I were to attempt to use b in any way, a NullPointerException would result. This is by far the most common run time error in Java.
In order to use b, I must first construct a JButton object using the new command:
b = new JButton(“hello”); // construct a button
// with “hello” on it
The new command does the following:
· Allocates space for the new object in memory.
· Calls the constructor code for the object (in this case, storing “hello” as the JButton’s label). We will talk more about this later.
· Returns a reference to the new object (which is assigned to b).
b now refers to an actual object, so it now may be used:
+------+
b ----> | hello |
+------+
References and Assignment/Equality
An important thing to understand is that the assignment and equality operators (= and ==) do not work well with objects, as the both refer to the address of the objects involved. For example, if I created another JButton:
JButton b1 = new JButton(“another”);
+------+
b1 ---> | another |
+------+
And then used assignment to copy one button to another:
b1 = b;
I would wind up with two references to the same object:
+------+
b ----> | hello |
/ +------+
/
/ +------+
b1 | another |
+------+
This is not a good idea, as changing b1 would unexpectedly change b, and vice-versa.
The same problems hold for using == for comparison, as it only checks whether its operands are the same object. For example, were I to create another button identical to b:
JButton b2 = new JButton(“hello”);
If I were to compare the two:
if (b == b2) {… }
The result would be false, as b and b2 are not the same object.
Deallocation with Garbage Collection
One thing you may have noticed in the above examples is that after b1 was assigned b’s reference, nothing points to the “another” button any more:
+------+
b ----> | hello |
/ +------+
/
/ +------+
b1 | another |
+------+
This means that the memory taken up by the “another” button is wasted, as it is inaccessible to the program. In C/C++ this must be dealt with by explicitly deallocating the memory space (with the delete command). This is not completely safe, and could potentially cause program crashes – for example, what if you delete an object that the program is still using?
Java takes a different approach, using a method called garbage collection to automatically deallocate unused memory. At regular intervals, it sweeps through the memory in its “sandbox”, searching for any objects that are not currently referred to by any variables in the program, and deallocating the memory of such objects.
This takes time, of course, which is the tradeoff for the safety of not allowing the programmer to delete objects explicitly.
Arrays and Strings
Arrays and Strings are also treated somewhat like objects in Java, so we will introduce them in some detail (more detail will be given after you have learned a bit more about object-oriented syntax).
Arrays
The most important thing to understand about arrays in Java is that they must be allocated with the new command like other objects.
For example, to declare an array of integers called A in Java, I would do the following:
int[] A;
Note the syntax is a little different from that of C, but makes sense if you think about it (particularly in the context of C’s function prototypes). int[] is the name of a type – in this case, “integer array”. The standard syntax for declaring variables in most languages is “typename variablename”, and that is what we are doing here.
However, at this point A does not actually refer to an array, but to null.
A ----> null
We must allocate that array (setting it’s size as well) with the new command:
A = new int[10];
The array A now points to an array of 10 integers (all currently 0).
A ----> [0][0][0][0][0][0][0][0][0][0]
At this point A can be used like any other array.
Multidimensional arrays are also allowed in Java. As in C, each dimension is in its own set of square brackets. For example:
int[][] B = new int[5][3];
Another thing to understand is that if an array contains objects, not only must the array be allocated, but so must the objects in those arrays. For example, the following statement creates an array of 3 buttons, but at this point all of those buttons are null.
JButton buttons = new JButton[3]; // buttons ---> [null][null][null]
To use the array, we must also construct the buttons it stores:
buttons[0] = new JButton(“Larry”);
buttons[1] = new JButton(“Curley”);
buttons[2] = new JButton(“Moe”);
Strings
Strings are also objects in Java. There are two main things to understand about Strings:
· Strings are not arrays of characters in Java. A more efficient representation is used, saving much time and space.
· Strings are immutable – that is, you cannot change any characters in an existing String (you can, however, assign that String variable a reference to a new String object).
You can create Strings using the new command:
String name = new String(“Fred”);
However, Java lets you use the simpler syntax:
String name = “Fred”;
While you cannot change the contents of a string, there are other useful things you can do, which will be covered after you have learned more about object-oriented syntax in Java. However, one very useful operator you need to know about is the + sign for concatenation.
For example:
String firstName = “Fred”;
String lastName = “Flintstone”;
String wholeName = firstName + “ “ + lastName;
Concatenation is also a nice shortcut for converting numeric types into Strings (to display in applets, for example). Anything concatenated to the end of a String is also converted into a String. For example:
int age = 29;
String ageString = “Age: “ + age; // result is “Age: 29”
Therefore, the simplest way to convert a number to a String is to just concatenate it to the empty string:
int num = 37;
String numString = “”+37; // result is “37”
The “Hello World!” Program
Strings are a central part of the very simplest programs that you can write in Java. We demonstrate them with the traditional “hello world” program below:
public class HelloWorld {
public static void main(String[] args) {
System.out.println(“Hello World!”);
}
}
A few notes about this program:
· As mentioned earlier, everything in Java is an object in a class. This is why the entire program is enclosed inside the public class HelloWorld { .. }. We will talk more about classes in the next section.
· You probably recognize void main from C as being the main program (we will talk about what public static means later). The String[] args is there to allow command line arguments to be passed to main. We will talk more about main programs in the section about static methods.
· The function takes a String as its parameter and displays it on the screen. It is roughly equivalent to cout < in C++. We will also talk about why it is in this form in the section about static methods.
Copyright © 2000 by Dr. John R. Sullins