< Zurück | Inhalt | Weiter >

3.2.1 Scalar Types

Java has a number of built-in scalar (in this context, nonobject) types. We discuss these below.


3.2.1.1 Integer Types

Java defines four integer types—byte, short, int, and long. Unlike some languages, Java defines the precision, that is, the bit size, of these types.

byte: 8 bits

short: 16 bits

int: 32 bits

long: 64 bits

For Java, the goal is “compile once, run anywhere.” Defining that int means 32 bits—everywhere—helps to achieve this goal. By contrast, when C language was first defined, its goal was different: to be available quickly on a variety of architectures, not to produce object code that would be portable be- tween architectures. Thus, for C, the choice was up to the compiler developer to choose a size that was most “natural” (i.e., convenient) for that particular architecture.2 This would make it easiest on the compiler writer. It succeeded—C was an easy language to implement, and it spread widely.

Back to Java. Note that all these values are signed. Java has no “unsigned” type.

Note also that byte is listed here. It can be treated as a numeric value, and calculations performed on it. Note especially that it is a signed number (i.e., values range from –128 to 127 and not from 0 to 255). Be careful when pro- moting a byte to an int (or other numeric value). Java will sign-extend on the promotion. If the value in the byte variable was a character (e.g., an ASCII value) then you really wanted it treated like an unsigned value. To assign such a value to an int you’ll need to mask off the upper bits, as in Example 3.1.

You may never encounter such a situation, but if you are ever working with bytes (e.g., byte arrays) and start to mess with the individual bytes, don’t say we didn’t warn you.



image

2. In fact, C’s only rule is that a short int will not be longer than an int and a long will not be shorter than an int. It is both ANSI and K&R compatible for all integer types in a C compiler to be the same size!


image

Example 3.1 Coercing a byte to int as if the byte were unsigned

byte c; int ival;

...

ival = ((int) c) && 0xFF; // explicit cast needed


image


3.2.1.2 Floating Point Types

Java provides two different precisions of floating point numbers. They are:

float: 32 bits

double: 64 bits

The float type is not very useful at that precision, so double is much more commonly seen. For other situations where precision is important, but you can spare some cycles, consider the BigDecimal and BigInteger object classes.

Java floating point numbers are specified to follow the IEEE floating point standard, IEEE 754.


3.2.1.3 Other Types

Java also has a boolean type, along with constants true and false. In Java, unlike C/C++, boolean values are a distinct type, and do not convert to numeric types. For example, it is common in C to write:


if (strlen(instr)) { strcpy(buffer, instr);

}


In this case, the integer result of strlen() is used as a boolean, where 0 is false and any other value is true. This doesn’t work in Java. The expression must be of a boolean type.

Java also has a char type, which is not the same as a byte. The char is a

character, and in Java, characters are represented using Unicode (UTF-16). They take two bytes each.

For more discussion on the differences between bytes and chars and about Unicode, read the Java tutorial on the java.sun.com Web site or visit www.unicode.org, the international standard’s Web site.


3.2.1.4 Operators

Before we move on to the topic of arrays (which are sort of a hybrid scalar/ object type in Java), let’s spend a moment on the operators that can be used in expressions (Table 3.1). Most deal with numeric or boolean operands. For completeness, we’ll include the operators that deal exclusively with arrays (the “[]”) and classes (“.”, new, and instanceof), even though we haven’t discussed them yet.

Operators listed on the same row in the table have the same precedence. Operators with the same precedence, except for the unary operators, group from left to right. Unary operators group from right to left.


3.2.1.5 Arrays

Example 3.2 demonstrates the array syntax in Java.


image

Example 3.2 Example array syntax

int [] oned = new int[35]; // array = new type[size] int alta [] = {1, 3, 5, 14, 11, 6, 24}; // alternative syntax plus

// initialization

int j=0;


for(int i=0; i<35; i++) {

oned[i] = valcomp(i, prop, alta[j]); // array[index] if (++j > alta.length) { // array.length

j = 0;

}

}


image


The array can be declared with the [] on either side of the variable name. While our example uses the primitive type int, array syntax looks just the same for any objects.

Note that in Java, one doesn’t declare the size of the array. It’s only in creating the array with a new that the array gets created to a particular size. (The {...} syntax is really just a special compiler construct for what is essentially a new followed by an assignment of values.)

Multidimensional arrays follow the syntax of simple arrays, but with additional adjacent square brackets, as shown in Example 3.3.


Table 3.1 Arithmetic and logical Java operators in order of precedence


image

Operators


image

[] .

- ++ -- ! ~

(type) new

* / %

+ -

<< >> >>>

< > <= >=

instanceof


== !=

&

^

| &&

||

?:


= += -= *= /=

%= <<= >>=

>>>= &= ^= |=

Explanation

array indexing, member reference

unary operators: negate, increment, decrement, logical-not, bitwise-not coercion, or casting to a different type; creating a new object multiplication, division, remainder

addition, subtraction

shift-left, shift-right-sign-extend, shift-right-zero-fill

less-than, greater-than, less-or-equal, greater-or-equal, comparing object types

equal, not-equal

bitwise-and (boolean for boolean operands with no short-circuit)* bitwise-xor (with boolean operands it is a boolean-xor)**

bitwise-or (boolean for boolean operands with no short-circuit)* logical-and (with short-circuit)*

logical-or (with short-circuit)*

Inline if expression, e.g., a ? b : c says, if a is true, then the value is b, else it is c.

Assignment; those with an operator, as in a op= b will perform the operation a op b then assign the result back to a.


image


* In Java there are two ways to do a boolean AND operation: using & or &&. Remember that for “a AND b”, if either is false, then the result is false. That means that if “a” is false, there is no need to evaluate “b” because it will not affect the result. Skipping the evaluation of “b” in this case is called short-circuiting. Java will use short-circuit evaluation when using the && operator, but not &. The same applies to the OR operators || and | where Java can short-circuit on a true evaluation of the first operand for ||. This is an important distinction when “a” and “b” are not just simple variable references but rather method calls or other complex expressions, especially ones with side effects.

** XOR is exclusive or, where the result of “a XOR b” is true if “a” or “b” is true, but not both. For bitwise operands, “a” and “b” refer here to bits in the operand; for boolean operands it is the one value. Examples: 5^6 is 3; true^false is true but true^true is false.

image


image

Example 3.3 Example two-dimensional array syntax

int [][] ragtag = new int[35][10];


for (int i=0; i<35; i++) { for (int j=0; j<10; j++) {

ragtag[i][j] = i*j;

} // next j

} // next i


image


Multidimensional arrays are built as arrays of arrays. Therefore, we can actually allocate it in a piecemeal fashion and have ragged-edged arrays, where each row has a different number of columns, as shown in Example 3.4.


image

Example 3.4 Ragged two-dimensional array syntax

int [][] ragtag = new int[17][];


for (int i=0; i<17; i++) { ragtag[i] = new int[10+i];

} // next i


for (int i=0; i<17; i++) {

System.out.println("ragtag["+i+"] is "+ragtag[i].length+" long.");

} // next i


image


For a fuller discussion of arrays, see Chapter 9 of Eckel or Chapter 6 of Lewis&Loftus.