Method Invocation Context
Method invocation conversions that can occur in a method invocation context are shown in the third column of Table 2.17. Note that method invocation and assignment conversions differ in one respect: Method invocation conversions do not include the implicit narrowing conversion performed for non-long integral constant expressions.
// Assignment: (1) Implicit narrowing followed by (2) boxing.
Character space1 = 32; // Character <-(2)– char <-(1)– int
// Invocation of method with signature: valueOf(char)
Character space2 = Character.valueOf(32); // Compile-time error!
// Call signature: valueOf(int)
Character space3 = Character.valueOf((char)32); // OK!
// Call signature: valueOf(char)
A method invocation conversion involves converting each argument value in a method or constructor call to the type of the corresponding formal parameter in the method or constructor declaration.
Method invocation conversions involving parameters of primitive data types are discussed in §3.10, p. 129, and those involving reference types are discussed in §5.8, p. 261.
Casting Context of the Unary Type Cast Operator (type)
Java, being a strongly typed language, checks for type compatibility (i.e., it checks whether a type can substitute for another type in a given context) at compile time. However, some checks are possible only at runtime (e.g., which type of object a reference actually denotes during execution). In cases where an operator would have incompatible operands (e.g., assigning a double to an int), Java demands that a type cast be used to explicitly indicate the type conversion. The type cast construct has the following syntax:
(
type
)
expression
The cast operator (type) is applied to the value of the expression. At runtime, a cast results in a new value of type, which best represents the value of the expression in the old type. We use the term casting to mean applying the cast operator for explicit type conversion.
However, in the context of casting, implicit casting conversions can take place. These casting conversions are shown in the fourth column of Table 2.17. Casting conversions include more conversion categories than the assignment or the method invocation conversions. In the code that follows, the comments indicate the category of the conversion that takes place because of the cast operator on the right-hand side of each assignment—although casts are only necessary for the sake of the assignment at (1) and (2).
long l = (long) 10; // Widening primitive conversion: long <— int
int i = (int) l; // (1) Narrowing primitive conversion: int <— long
Object obj = (Object) “7Up”; // Widening ref conversion: Object <— String
String str = (String) obj; // (2) Narrowing ref conversion: String <— Object
Integer iRef = (Integer) i; // Boxing: Integer <— int
i = (int) iRef; // Unboxing: int <— Integer
A casting conversion is applied to the value of the operand expression of a cast operator. Casting can be applied to primitive values as well as references. Casting between primitive data types and reference types is not permitted, except where boxing and unboxing is applicable. Boolean values cannot be cast to other data values, and vice versa. The reference literal null can be cast to any reference type.
Examples of casting between primitive data types are provided in this chapter. Casting reference values is discussed in §5.11, p. 269.