Source: http://spec-zone.ru/Java/JLS/1/5.doc.html
Timestamp: 2019-04-23 06:55:38+00:00

Document:
Every Java expression has a type that can be deduced from the structure of the expression and the types of the literals, variables, and methods mentioned in the expression. It is possible, however, to write an expression in a context where the type of the expression is not appropriate. In some cases, this leads to an error at compile time; for example, if the expression in an if statement (§14.8) has any type other than boolean, a compile-time error occurs. In other cases, the context may be able to accept a type that is related to the type of the expression; as a convenience, rather than requiring the programmer to indicate a type conversion explicitly, the Java language performs an implicit conversion from the type of the expression to a type acceptable for its surrounding context.
A conversion from type Object (§20.1) to type Thread (§20.20) requires a run-time check to make sure that the run-time value is actually an instance of class Thread or one of its subclasses; if it is not, an exception is thrown.
A conversion from type Thread to type Object requires no run-time action; Thread is a subclass of Object, so any reference produced by an expression of type Thread is a valid reference value of type Object.
A conversion from type int to type long requires run-time sign-extension of a 32-bit integer value to the 64-bit long representation. No information is lost.
A conversion from type double to type long requires a nontrivial translation from a 64-bit floating-point value to the 64-bit integer representation. Depending on the actual run-time value, information may be lost.
There are five conversion contexts in which conversion of Java expressions may occur. Each context allows conversions in some of the categories named above but not others. The term "conversion" is also used to describe the process of choosing a specific conversion for such a context. For example, we say that an expression that is an actual argument in a method invocation is subject to "method invocation conversion," meaning that a specific conversion will be implicitly chosen for that expression according to the rules for the method invocation argument context.
One conversion context is the operand of a numeric operator such as + or *. The conversion process for such operands is called numeric promotion. Promotion is special in that, in the case of binary operators, the conversion chosen for one operand may depend in part on the type of the other operand expression.
Assignment conversion (§5.2, §15.25) converts the type of an expression to the type of a specified variable. The conversions permitted for assignment are limited in such a way that assignment conversion never causes an exception.
Method invocation conversion (§5.3, §15.8, §15.11) is applied to each argument in a method or constructor invocation and, except in one case, performs the same conversions that assignment conversion does. Method invocation conversion never causes an exception.
Casting conversion (§5.4) converts the type of an expression to a type explicitly specified by a cast operator (§15.15). It is more inclusive than assignment or method invocation conversion, allowing any specific conversion other than a string conversion, but certain casts to a reference type may cause an exception at run time.
String conversion (§5.4, §15.17.1) allows any type to be converted to type String.
Numeric promotion (§5.6) brings the operands of a numeric operator to a common type so that an operation can be performed.
// float. This is a binary numeric promotion.
Specific type conversions in Java are divided into six categories.
A conversion from a type to that same type is permitted for any type. This may seem trivial, but it has two practical consequences. First, it is always permitted for an expression to have the desired type to begin with, thus allowing the simply stated rule that every expression is subject to conversion, if only a trivial identity conversion. Second, it implies that it is permitted for a program to include redundant cast operators for the sake of clarity.
The only permitted conversion that involves the type boolean is the identity conversion from boolean to boolean.
Widening primitive conversions do not lose information about the overall magnitude of a numeric value. Indeed, conversions widening from an integral type to another integral type and from float to double do not lose any information at all; the numeric value is preserved exactly. Conversion of an int or a long value to float, or of a long value to double, may result in loss of precision-that is, the result may lose some of the least significant bits of the value. In this case, the resulting floating-point value will be a correctly rounded version of the integer value, using IEEE 754 round-to-nearest mode (§4.2.4).
A widening conversion of a signed integer value to an integral type T simply sign-extends the two's-complement representation of the integer value to fill the wider format. A widening conversion of a character to an integral type T zero-extends the representation of the character value to fill the wider format.
Despite the fact that loss of precision may occur, widening conversions among primitive types never result in a run-time exception (§11).
thus indicating that information was lost during the conversion from type int to type float because values of type float are not precise to nine significant digits.
Narrowing conversions may lose information about the overall magnitude of a numeric value and may also lose precision.
A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.
A narrowing conversion of a character to an integral type T likewise simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the resulting value to be a negative number, even though characters represent 16-bit unsigned integer values.
If the floating-point number is NaN (§4.2.3), the result of the first step of the conversion is an int or long 0.
If T is long, and this integer value can be represented as a long, then the result of the first step is the long value V.
Otherwise, if this integer value can be represented as an int, then the result of the first step is the int value V.
The value must be too small (a negative value of large magnitude or negative infinity), and the result of the first step is the smallest representable value of type int or long.
The value must be too large (a positive value of large magnitude or positive infinity), and the result of the first step is the largest representable value of type int or long.
If T is int or long, the result of the conversion is the result of the first step.
If T is byte, char, or short, the result of the conversion is the result of a narrowing conversion to type T (§5.1.3) of the result of the first step.
The results for char, int, and long are unsurprising, producing the minimum and maximum representable values of the type.
The results for byte and short lose information about the sign and magnitude of the numeric values and also lose precision. The results can be understood by examining the low order bits of the minimum and maximum int. The minimum int is, in hexadecimal, 0x80000000, and the maximum int is 0x7fffffff. This explains the short results, which are the low 16 bits of these values, namely, 0x0000 and 0xffff; it explains the char results, which also are the low 16 bits of these values, namely, '\u0000' and '\uffff'; and it explains the byte results, which are the low 8 bits of these values, namely, 0x00 and 0xff.
A narrowing conversion from double to float behaves in accordance with IEEE 754. The result is correctly rounded using IEEE 754 round-to-nearest mode. A value too small to be represented as a float is converted to positive or negative zero; a value too large to be represented as a float is converted to a (positive or negative) infinity. A double NaN is always converted to a float NaN.
Despite the fact that overflow, underflow, or other loss of information may occur, narrowing conversions among primitive types never result in a run-time exception (§11).
From any class type S to any interface type K, provided that S implements K.
From the null type to any class type, interface type, or array type.
From any interface type J to any interface type K, provided that J is a subinterface of K.
From any interface type to type Object.
From any array type to type Object.
From any array type to type Cloneable.
From any array type SC to any array type TC, provided that SC and TC are reference types and there is a widening conversion from SC to TC.
Such conversions never require a special action at run time and therefore never throw an exception at run time. They consist simply in regarding a reference as having some other type in a manner that can be proved correct at compile time.
See §8 for the detailed specifications for classes, §9 for interfaces, and §10 for arrays.
From type Object to any array type.
From type Object to any interface type.
From any interface type J to any class type T that is not final.
From any interface type J to any class type T that is final, provided that T implements J.
From any interface type J to any interface type K, provided that J is not a subinterface of K and there is no method name m such that J and K both declare a method named m with the same signature but different return types.
From any array type SC to any array type TC, provided that SC and TC are reference types and there is a narrowing conversion from SC to TC.
Such conversions require a test at run time to find out whether the actual reference value is a legitimate value of the new type. If not, then a ClassCastException is thrown.
There is a string conversion to type String from every other type, including the null type.
There is no permitted conversion from any reference type to any primitive type.
Except for the string conversions, there is no permitted conversion from any primitive type to any reference type.
There is no permitted conversion to the type boolean other than the identity conversion.
There is no permitted conversion from the type boolean other than the identity conversion and string conversion.
There is no permitted conversion other than string conversion from class type S to a different class type T if S is not a subclass of T and T is not a subclass of S.
There is no permitted conversion from class type S to interface type K if S is final and does not implement K.
There is no permitted conversion other than string conversion from interface type J to class type T if T is final and does not implement J.
There is no permitted conversion from interface type J to interface type K if J and K declare methods with the same signature but different return types.
There is no permitted conversion from any array type to any interface type, except to the interface type Cloneable, which is implemented by all arrays.
There is no permitted conversion from array type SC to array type TC if there is no permitted conversion other than a string conversion from SC to TC.
The expression is a constant expression of type int.
The type of the variable is byte, short, or char.
The value of the expression (which is known at compile time, because it is a constant expression) is representable in the type of the variable.
If the type of the expression cannot be converted to the type of the variable by a conversion permitted in an assignment context, then a compile-time error occurs.
If the type of an expression can be converted to the type a variable by assignment conversion, we say the expression (or its value) is assignable to the variable or, equivalently, that the type of the expression is assignment compatible with the type of the variable.
A value of primitive type must not be assigned to a variable of reference type; an attempt to do so will result in a compile-time error. A value of type boolean can be assigned only to a variable of type boolean.
because not all short values are char values, and neither are all char values short values.
A value of reference type must not be assigned to a variable of primitive type; an attempt to do so will result in a compile-time error.
A value of the null type (the null reference is the only such value) may be assigned to any reference type, resulting in a null reference of that type.
If T is a class type, then S must either be the same class as T, or S must be a subclass of T, or a compile-time error occurs.
If T is an interface type, then S must implement interface T, or a compile-time error occurs.
If T is an array type, then a compile-time error occurs.
If T is a class type, then T must be Object, or a compile-time error occurs.
If T is an interface type, then T must be either the same interface as S or a superinterface of S, or a compile-time error occurs.
If T is an interface type, then a compile-time error occurs unless T is the interface type Cloneable, the only interface implemented by arrays.
TC and SC are the same primitive type.
TC and SC are both reference types and type SC is assignable to TC, as determined by a recursive application of these compile-time rules for assignability.
See §8 for the detailed specifications of classes, §9 for interfaces, and §10 for arrays.
The following test program illustrates assignment conversions on reference values, but fails to compile because it violates the preceding rules, as described in its comments. This example should be compared to the preceding one.
The value of veclong cannot be assigned to a Long variable, because Long is a class type (§20.8) other than Object. An array can be assigned only to a variable of a compatible array type, or to a variable of type Object.
The value of veclong cannot be assigned to vecshort, because they are arrays of primitive type, and short and long are not the same primitive type.
The value of cpvec can be assigned to pvec, because any reference that could be the value of an expression of type ColoredPoint can be the value of a variable of type Point. The subsequent assignment of the new Point to a component of pvec then would throw an ArrayStoreException (if the program were otherwise corrected so that it could be compiled), because a ColoredPoint array can't have an instance of Point as the value of a component.
Method invocation conversion is applied to each argument value in a method or constructor invocation (§15.8, §15.11): the type of the argument expression must be converted to the type of the corresponding parameter. Method invocation contexts allow the use of an identity conversion (§5.1.1), a widening primitive conversion (§5.1.2), or a widening reference conversion (§5.1.4).
causes a compile-time error because the integer literals 12 and 2 have type int, so neither method m matches under the rules of (§15.11.2). A language that included implicit narrowing of integer constants would need additional rules to resolve cases like this example.
String conversion applies only to the operands of the binary + operator when one of the arguments is a String. In this single special case, the other argument to the + is converted to a String, and a new String which is the concatenation of the two strings is the result of the +. String conversion is specified in detail within the description of the string concatenation + operator (§15.17.1).
Casting conversion is applied to the operand of a cast operator (§15.15): the type of the operand expression must be converted to the type explicitly named by the cast operator. Casting contexts allow the use of an identity conversion (§5.1.1), a widening primitive conversion (§5.1.2), a narrowing primitive conversion (§5.1.3), a widening reference conversion (§5.1.4), or a narrowing reference conversion (§5.1.5). Thus casting conversions are more inclusive than assignment or method invocation conversions: a cast can do any permitted conversion other than a string conversion.
A value of a primitive type can be cast to another primitive type by identity conversion, if the types are the same, or by a widening primitive conversion or a narrowing primitive conversion.
A value of a primitive type cannot be cast to a reference type by casting conversion, nor can a value of a reference type be cast to a primitive type.
If T is a class type, then S and T must be related classes-that is, S and T must be the same class, or S a subclass of T, or T a subclass of S; otherwise a compile-time error occurs.
If S is not a final class (§8.1.2), then the cast is always correct at compile time (because even if S does not implement T, a subclass of S might).
If S is a final class (§8.1.2), then S must implement T, or a compile-time error occurs.
If T is an array type, then S must be the class Object, or a compile-time error occurs.
If T is a class type that is not final (§8.1.2), then the cast is always correct at compile time (because even if T does not implement S, a subclass of T might).
If T is a class type that is final (§8.1.2), then T must implement S, or a compile-time error occurs.
If T is an interface type and if T and S contain methods with the same signature (§8.4.2) but different return types, then a compile-time error occurs.
If T is a class type, then if T is not Object, then a compile-time error occurs (because Object is the only class type to which arrays can be assigned).
TC and SC are reference types and type SC can be cast to TC by a recursive application of these compile-time rules for casting.
The cast can be determined to be correct at compile time. A cast from the compile-time type S to compile-time type T is correct at compile time if and only if S can be converted to T by assignment conversion (§5.2).
If T is a class type, then R must be either the same class (§4.3.4) as T or a subclass of T, or a run-time exception is thrown.
If T is an interface type, then R must implement (§8.1.4) interface T, or a run-time exception is thrown.
If T is an array type, then a run-time exception is thrown.
If T is a class type, then T must be Object (§4.3.2, §20.1), or a run-time exception is thrown.
If T is an interface type, then R must be either the same interface as T or a subinterface of T, or a run-time exception is thrown.
If T is an interface type, then a run-time exception is thrown unless T is the interface type Cloneable, the only interface implemented by arrays (this case could slip past the compile-time checking if, for example, a reference to an array were stored in a variable of type Object).
TC and RC are the same primitive type.
TC and RC are reference types and type RC can be cast to TC by a recursive application of these run-time rules for casting.
If a run-time exception is thrown, it is a ClassCastException (§11.5.1.1, §20.22).
Here the first compile-time error occurs because the class types Long and Point are unrelated (that is, they are not the same, and neither is a subclass of the other), so a cast between them will always fail.
The second compile-time error occurs because a variable of type EndPoint can never reference a value that implements the interface Colorable. This is because EndPoint is a final type, and a variable of a final type always holds a value of the same run-time type as its compile-time type. Therefore, the run-time type of variable e must be exactly the type EndPoint, and type EndPoint does not implement Colorable.
Numeric promotion is applied to the operands of an arithmetic operator. Numeric promotion contexts allow the use of an identity conversion (§5.1.1) or a widening primitive conversion (§5.1.2).
Numeric promotions are used to convert the operands of a numeric operator to a common type so that an operation can be performed. The two kinds of numeric promotion are unary numeric promotion (§5.6.1) and binary numeric promotion (§5.6.2). The analogous conversions in C are called "the usual unary conversions" and "the usual binary conversions."
Numeric promotion is not a general feature of Java, but rather a property of the specific definitions of the built-in operations.
If the operand is of compile-time type byte, short, or char, unary numeric promotion promotes it to a value of type int by a widening conversion (§5.1.2).
Otherwise, a unary numeric operand remains as is and is not converted.
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
Otherwise, both operands are converted to type int.
The example converts the ASCII character G to the ASCII control-G (BEL), by masking off all but the low 5 bits of the character. The 7 is the numeric value of this control character.

References: §15
 §15
 §15
 §15
 V.

 V.

 §8
 §9
 §10
 §8
 §9
 §10
 §15
 §20
 §20