public class LeapYear {
public static void main(String[] args) {
This program tests whether an integer corresponds to a leap year in the Gre-gorian calendar. A year is a leap year if it is divisible by 4 (2004) unless it is divisible by 100 in which case it is not (1900), unless it is divisible by 400 in which case it is (2000).
32
In the present context, we are interested in boolean expressions because we use them to control the behavior of our programs. Typically, a particular condition of interest is specified as a boolean variable and a piece of program code is written to execute one set of statements if the variable is
true and a different set of statements if the variable is false. The mechanics of doing so are the topic of Section X.
Comparisons. Some mixed-type operations take operands of one type and produce a result of another type. The most important built-in operations of this kind are the comparison operations ==, !=, <, <=, >, and >=, which all are defined for each primitive numeric type and which all produce a boolean
result. As we will see in Section X, these operations play a critical role in the process of developing programs more sophisticated than the sequence-of-statements programs that we have been considering. The meanings of these operations are summarized in the following table:
Since operations are defined only with respect to data types, each of these symbols stands for many operations, one for each data type. It is required that both operands be of the same type, and the result is always boolean. Even without going into the details of number representation that we con-sider in Section X, it is clear, on reflection, that the operations for the various types are really quite different: for example, it is one thing to compare two
ints to check that 2 == 2 is true but quite another to compare two doubles to check whether 2.1 == .0021E3 is true or false.
op a op b true false
== equal a is equal to b 2 == 2 2 == 3
!= not equal !(a == b) 3 != 2 2 != 2
< less than a is less than b 2 < 13 2 < 2
<= less than or equal (a < b) || (a == b) 2 <= 2 3 <= 2
> greater than !(a <= b) 13 > 2 2 > 13
>= greater than or equal !(a < b) 3 >= 2 2 >= 3
Comparison operations, with boolean logic, provide the basis for decision-making in Java programs. Program 2.1.4 is a simple example of their use, and you can find other examples in the exercises at the end of this section. In Section 2.2 we will see the critical role that such expressions play in controlling the flow of execution of the statements in our programs.
Type conversion. One of the first rules of programming in Java is that you should always be aware of the type of data that your program is processing.
Only by knowing the type can you know precisely what set of values each variable can have, what literals you can use, and what operations you can per-form. But typical programming tasks involve processing multiple types of data, and we often need to be able to convert data from one type to another.
There are several ways to do so in Java.
Explicit type conversion. You can use a method that takes an argument of one type (the value to be converted) and returns a result of another type. For example, the library method Math.round takes a double argument and returns an long result: the nearest integer to the argument. Thus, for exam-ple, Math.round(3.14159) and Math.round(2.71828) are both of type
long and have the same value (3). Our use of the library methods Inte-ger.parseInt and Double.parseDouble in the programs in this section are also examples of this kind of conversion. In Section 2.4, you will learn how to implement such methods.
Automatic conversion for numbers. You can use data of any primitive numeric type where a value whose type has a larger range of values is expected. Java automatically converts to the type with the larger range. For example, we used numbers all of type double in Program 2.1.3, so there is no conversion, but we might instead have chosen to make b and c of type int (using
Inte-ger.parseInt to convert the command-line arguments). Then the expres-sion b * b - 4 . 0 * c requires t y pe conversion, which Java would do automatically: first, it would covert c to double and multiply by the double literal 4.0 to get a double result. As for the other term, it would compute the value b*b and then convert to double for the subtraction, leaving a double result. Or, we might have written b*b - 4*c. In that case, the program would evaluate the expression b*b - 4*c as an int and then automatically convert
34
the result to double, because that is what Math.sqrt expects. Java does this kind of type conversion automatically because your intent is clear and it can do so with no loss of information. On the other hand, if the conversion might involve loss of information, for example if you try to assign a double to an
int, you will get an error message from the compiler.
Explicit cast. Java has some built-in type conversion methods for primitive types that you can use when you are aware that you might lose information, but you have to make your intention to do so explicit using a device called a cast. You cast a variable or an expression from one primitive type to another simply by prepending the desired type name within parentheses: for example, the expression (int) 3.14159 is a cast from double to int that is of type
int with value 3. Java has built-in conversion methods defined for casts among primitive numeric types that implement reasonable and convenient approaches to throwing away information (for a full list, see Appendix X).