Type Conversions

   

A critical part of understanding data types in a programming language is knowing how expressions that contain different types are evaluated. For example, how does the language handle situations where a float is assigned to a double or a byte is added to an int ? Java is a strongly typed language, so issues like this are resolved at compile time. Extensive type checking is performed (to help detect programmer errors) and strict restrictions are imposed on which values can be converted from one type to another.

There are really two different kinds of conversions:

  • Implicit conversions occur any time a value is of a different type than that required in an expression and the compiler can safely convert it to what is required. This happens without any intervention on your part.

  • Explicit conversions occur when you deliberately change the data type of a value. This is called casting.

Note

In C, almost any data type can be converted to almost any other across an assignment statement. This is not the case in Java, and implicit conversions between numeric data types are only performed if they do not result in loss of precision or magnitude. Any attempted conversion that would result in such a loss produces a compiler error, unless you use an explicit cast.


Implicit Conversions

Java performs a number of implicit type conversions when evaluating expressions that contain primitives. The rules for these conversions are highly restrictive , which actually makes them simpler to understand than those in C or even C++. The fundamental rule for implicit conversions is that they must be widening conversions as opposed to narrowing ones. This means that an implicit conversion can only convert a primitive type to one with a larger bit representation. For example, implicit conversions include byte to int, int to long, and float to double. A notable exception is that char cannot be converted to short. Both types are 16-bit, but remember that the integer equivalent for a char is treated as an unsigned value, so it can only be converted to a 32-bit or greater representation.

Implicit conversions for unary operators (such as ++ or “ “) are simple: Operands of type byte, short, or char are converted to int, and all others are left alone.

For binary operators, the situation is only slightly more complex. For operations involving only integer operands, if either of the operands is long, the other is converted to long ; otherwise , both operands are converted to int. The result of the expression is an int unless its magnitude requires a long for storage. For operations involving at least one floating-point operand, if either of the operands is double, the other is also converted to double and the result of the expression is a double ; otherwise, both operands are converted to float, and the result of the expression is also a float. Consider the expressions in Listing 5.1.

Listing 5.1 Expressions Showing Implicit Type Conversions
 short width; long length, area; double totalCost, costPerFoot; // In the multiplication below, width will be converted to a // long, and the result of the calculation will be a long. area = length * width; // In the division below, area will be converted to a double, // and the result of the calculation will be a double. costPerFoot = totalCost / area; 

In addition to expressions, implicit conversions might also take place as part of method calls. This happens when a parameter is not of the same type specified in the method signature. Again, all widening conversions of primitive types are supported implicitly.

Implicit conversions safely take place at compile time without any effort on your part. If the compiler cannot perform an implicit conversion, you will get a compiler error that you can usually address with an explicit conversion.

Explicit Conversions Using the Cast Operator

Sometimes an implicit conversion might not be supported within an expression you need to evaluate, or you might need to force a type conversion for a specific need. Here you need to perform an explicit conversion using the cast operator. It is sometimes even helpful from a maintenance standpoint to use a cast where an implicit conversion would be performed anyway just to make the intent of the code more obvious.

The cast operator doesn't look like other operators, but it can be described in the same way. It is a unary operator that comes before its operand and consists of a type name inside parentheses. Casting an operand is an operation with high precedence that produces a variable of the type specified by the cast. This variable has the value of the original operand. The following example shows an example of a cast:

 float x = 2.0; float y = 1.7; x = ( (int)(x/y) * y); 

When x is divided by y in this example, the type of the result is a floating-point number. However, the value of x/y is explicitly converted to type int by the cast operator, resulting in a 1, not 1.2. So, the end result of this equation is that x equals 1.7. It wasn't an issue in this example, but truncation is always used instead of rounding when you cast a floating-point value to an integer. Also, note that you can cast a literal value in the same way a variable was cast in this example.

Unlike implicit conversions, narrowing conversions are allowed in addition to widening ones when casting. Narrowing conversions result in a loss of bits, so you should use them with caution. Narrowing conversions between integer types will lose data if the upper bits of a value are nonzero. Also, casting an integer to a float or double might also lose precision just as casting a double to a float likely will.

Explicit conversions are generally allowed between any primitives, but the compiler will reject some casts as illegal. In particular, you cannot cast a boolean to any other type or cast any other type to a boolean.

The cast operator applies to classes (see Chapter 7, "Classes" ) and interfaces (see Chapter 9, "Interfaces" ) in addition to primitives. An object can be cast to a superclass or any interface that it implements. An interface can be cast to any other interface that it extends.

See "Casting and Converting Reference Types,"

See "Referencing Interfaces,"

Note

Because casting involves an unconditional type conversion (if the conversion is legal), it is also sometimes known as type coercion.


Character Conversions

Characters can be implicitly converted to int, long, float, or double, or be cast to any primitive type other than boolean. However, casting a char to a type smaller than int might cause a loss of data.

Note

If you are using the Han character set (Chinese, Japanese, or Korean), you can lose data by casting a char into a short. Although both are 16-bit types, the upper bit of a short is reserved for the sign bit.


   


Special Edition Using Java 2 Standard Edition
Special Edition Using Java 2, Standard Edition (Special Edition Using...)
ISBN: 0789724685
EAN: 2147483647
Year: 1999
Pages: 353

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net