15. Data types, Operators, Documentation
Data types, Operators, Documentation
So far, we have been exploring a few basic ideas to do with OOP and using Java, and in the process we have happily used variables and data types without exploring them fully. This was ok as we were not really likely to run into too much trouble with the simple classes we have been implementing. We have reached the point however where it has become necessary to gain a fuller understanding of Java data types.
In Java, every variable must have a data type. A variable's data type determines the values that the variable can contain and the operations that can be performed on it. The Java programming language has two categories of data types: primitive and reference.
A variable of primitive type contains a single value of the appropriate size and format for its type: a number, a character, or a boolean value; in other words a primitive data type is not an object. The following table lists by type, all of the primitive data types supported by Java, their sizes, and a brief description of each.
| Type | Description | Size |
|---|---|---|
| Integers | ||
byte |
Small enough to be held by a single byte: -127 to +127 | 8 bits (1 byte) |
short |
Small enough to be held by two bytes: -32 767 to +32 767 | 16 bits (2 bytes) |
int |
Small enough to be held by four bytes: -2 147 483 647 to +2 147 483 647 | 32 bits (4 bytes) |
long |
Small enough to be held by eight bytes: -922 x 1016 to +922 x 1016 | 64 bits (8 bytes) |
| Real numbers | ||
float |
Single precision floating-point number: -(2-2-23) * 2127 to +(2-2-23) * 2127 | 32-bit IEEE 754 |
double |
Double precision floating-point number: -(2-2-52) * 21023 to +(2-2-52) * 21023 | 64-bit IEEE 754 |
| Other | ||
char |
A single character - delimited by single quotes, e.g. 'Q' | 16-bit Unicode character |
boolean |
A boolean value (true or false) |
|
A variable of reference type contains merely a reference to an object; arrays, classes and interfaces are of reference type.
The importance of data types
Data types in Java are important for several reasons. Firstly of course, all variables that you declare must be data typed as we have seen, and all method return values also. There is an implication of data typing that we haven't so far considered, and that is that you cannot supply the wrong data types to object constructors and instance methods. For example, in the Circle class we have to supply a radius to the constructor which must be a number of type double. This means that you can supply virtually any real number to the Circle(double aRadius) constructor, because Java will accept these as double values. However, if we had defined the constructor to be Circle(int aRadius), and had then tried to create a circle like this:
Circle myCircle = new Circle(23.7);
we would have generated an error - an integer variable cannot accept a double precision number.
This means that we must be careful when using the Java classes to be sure that we know what the expected data types of arguments are, or may need to be defined as. For example, double precision numbers are held by the double data type, and they can be anything from very large numbers containing a decimal point - 56548.90734E23, to very small numbers with a decimal point - 0.00004522E-19. We might have felt that nobody might want to create a circle object with a radius of billions of trillions of metres, and decided to define the constructor and methods to take single precision float values instead of double values because these would still allow very large radii:
public class Circle {
private float radius;
private float circumference;
private float area;
public Circle(float aRadius) {
radius = aRadius;
area = Math.PI*radius*radius;
circumference = 2*Math.PI*radius;
}
...
}
However, when we try to compile this class, we generate the following errors:
What has happened here is that Math.PI is a constant of type double - multiplying it by a value of type float and then trying to assign the result to a variable of type float could lead to an error in the precision of the number stored in the float variable, so the compiler refuses to compile the class. In other words, we defined circumference to be of type float; multiplying a double by a float results in a double - a double cannot be stored in a float variable. This kind of mistake is very easy to make! Fortunately, the compiler will catch most of them, but if you don't know what's causing the error it's very hard to fix it. This error has been caused by a discrepancy in the precision of the two data types - float has a lower precision than double.
When assigning a literal value to a variable, we must be careful. A number such as 234.98 could possibly be of type float, but it could just as easily qualify as type double. For this reason, when assigning literals to variables we should always make sure that there can be no confusion by using the Java notation that explicitly defines literals to be of a certain type.
| Literal | Data type |
|---|---|
| 236 | int |
| 9932L | long |
| 43.855 | double |
| 43.855D | double |
| 43.855F | float |
| 63.43e9 | double |
| 'B' | char |
| true | boolean |
| false | boolean |
Examples:
int num = 123; long longNum = 99765L; //L suffix types int to long double aDouble = 67.905; //decimal fraction ALWAYS of type double float aFloat = 459.221; //Error - assignation of double to float float myFloat = 56.982F; //F suffix types double to float char myChar = 'z'; //single quotes delimit type char boolean myBoole = true; //boolean values do not require quotesWe need to be careful when dividing and multiplying numbers, particularly integers. For example, it's easy to see that this is an error:
int anInt = 7/2; //stooopid...!
However, when we have defined variables, assigned numbers to them, and then work with them much later in the code this kind of error easily creeps in:
int result = 0; int aNum = 5; int myNum = 23; ... [many lines of code later] ... result = myNum * aNum; //no problem result = result-1/aNum; //Illegal assignment of double to int!Multiplication errors also creep in:
int result = 0;
int myInt = 14567329;
int anInt = 44492;
result = anInt * myInt; //Illegal assignment of long to int!
14567329 * 44492 produces a number too large to be of type int - do the math and see! The problem here is that just looking at the code it's not immediately apparent that this is the case.
A NOTE ON VARIABLE NAMES.
By Convention : Variable names begin with a lowercase letter, and class names begin with an uppercase letter. If a variable name consists of more than one word, the words are joined together, and each word after the first begins with an uppercase letter, like this: isVisibleTonight. The underscore character _ is acceptable anywhere in a name, but by convention is used only to separate words in constants because constants are all caps by convention, and therefore cannot be case-delimited:
final byte MONTHS_IN_YEAR = 12;
Note the keyword final in the constant declaration above. This is used to indicate that the variable is a constant, i.e. the value it is initialised to is the final value of this variable - it cannot under any circumstances be changed by code.
The final keyword can be applied to other entities too, such as methods and classes. final classes cannot be subclassed; final methods cannot be overriden.
CASTING ONE DATA TYPE INTO ANOTHER.
Java allows us to convert data of one type into another, provided the two data types allow such a conversion, i.e. are compatible. To do this, all that is required is to place the typename of the new data type in parentheses in front of the variable or expression which must be cast into the new type. For example, if we wish to convert a number of type double to type int, we do it in the following way:
double myDouble = 72.52634; int myInt = (int)myDouble; //returns 72Certain data types can be added or multiplied together (provided that the result is compatible with the final data type), but others cannot. For example a byte can usually be added to an int, but the reverse is only possible if the sum of the integer and the byte is small enough to be contained in the byte data type, i.e. the result must be between -127 and +127. A number can be 'added' (i.e. joined to) a String with the + operator, but a String cannot be added to a number:
int myInt = 71; myInt += "abc"; //No way, Josè! String aString = myInt + " abc"; //This works okAlthough numbers are primitive data types, Java does have number classes that allow numbers to be converted into objects:
Integer intObject = new Integer(33);
Double doubleObject = new Double(234.6578);
//cast (parse) string to int
Integer intFromString = Integer.parseInt("999");
Note that these number classes have capitalised names like any other Java class, so a Double object is therefore distinguishable from the primitive double type.
© G. Hearn, & University of the Western Cape, 2006






