Type checking
All programming languages must deal in one way or the other with type checking — the way that a language handles variables that store different types of data. Numbers, strings, and dates, for example, are commonly used data types available in most programming languages. Most programming languages also have several types of numbers, such as integers and real numbers.All languages must check data types, so make sure that you don’t try to do things that don’t make sense (such as multiplying the gross national product by your last name). The question is, does the language require you to declare every variable’s type so you can do type checking when it compiles your programs, or does the language do type checking only after it runs your program?
Some languages, such as Perl, are not as rigid about type checking as Java. For example, Perl does not require that you indicate whether a variable will contain an integer, a floating point number, or a string. Thus, all the following Java statements are allowed for a single variable named $a
:
$a = 5
$a = "Strategery"
$a = 3.14159
Here, three different types of data — integer, string, and double — have been assigned to the same variable.
Java, on the other hand, does complete type checking when the program is compiled. As a result, you must declare all variables as a particular type so that the compiler can make sure you use the variables correctly. The following bit of Java code, for example, won’t compile:
int a = 5;
String b = "Strategery";
String c = a * b;
If you try to compile these lines, you get an error message saying that Java can’t multiply an integer and a string.
In Java, every class you define creates a new type of data for the language to work with. Thus, the data types you have available to you in Java aren’t just simple predefined types, such as numbers and strings. You can create your own types. If you’re writing a payroll system, you might create an Employee
type. Then you can declare variables of type Employee
that can hold only Employee
objects. This capability prevents a lot of programming errors. Consider this code snippet:
Employee newHire;
newHire = 21;
This code creates a variable (newHire
) that can hold only Employee
objects. Then it tries to assign the number 21
to it. The Java compiler won’t let you run this program because 21
is a number, not an employee.
An important object-oriented programming feature of Java called inheritance adds an interesting — and incredibly useful — twist to type checking. Inheritance in Java is way too complicated to dive into just yet, so I’ll be brief here. In Java, you can create your own data types that are derived from other data types. Employees are people, for example, and customers are people too, so you might create a Person
class and then create Employee
and Customer
classes that both inherit the Person
class. Then you can write code like this:
Person p;
Employee e;
Customer c;
p = e; // This is allowed because an Employee is also a Person.
c = e; // This is not allowed because an Employee is not a Customer.
Exception handling
As Robert Burns said, “The best-laid schemes o’ mice an’ men gang oft agley, an’ lea’e us nought but grief an’ pain, for promis’d joy!” When you tinker with computer programming, you’ll quickly discover what he meant. No matter how carefully you plan and test your programs, errors happen, and when they do, they threaten to bring your whole program to a crashing halt.Java has a unique approach to error handling that’s superior (in my opinion) to that of any other language (except C#, which just copies Java’s approach). The Java Runtime Environment intercepts and folds errors of all types into a special type of object called an exception object. After all, Java is object-oriented through and through, so why shouldn’t its exception-handling features be object-oriented?
Java requires any statements that can potentially cause an exception to be bracketed by code that can catch and handle the exception. In other words, you, as the programmer, must anticipate errors that can happen while your program is running and make sure that those errors are dealt with properly. Although this necessity can be annoying, it makes the resulting programs more reliable.