Source: http://4e00.com/java/java-language-specification-v2/conversions.doc.html
Timestamp: 2019-04-19 12:14:02+00:00

Document:
Every expression written in the Java programming language 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.9) 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 language performs an implicit conversion from the type of the expression to a type acceptable for its surrounding context.
A conversion from type Object to type Thread 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.
There are five conversion contexts in which conversion of 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.
Assignment conversion (§5.2, §15.26) 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.9, §15.12) 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.5) converts the type of an expression to a type explicitly specified by a cast operator (§15.16). 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.18.1) allows any type to be converted to type String.
Specific type conversions in the Java programming language are divided into seven categories.
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. Conversions widening from float to double in strictfp expressions also preserve the numeric value exactly; however, such conversions that are not strictfp may lose information about the overall magnitude of the converted value.
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).
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 contain a method named m with the same signature but different return types.
There is no permitted conversion from interface type J to interface type K if J and K contain 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 types java.io.Serializable and Cloneable, which are implemented by all arrays.
Value set conversion is the process of mapping a floating-point value from one value set to another without changing its type.
If the value is an element of the float-extended-exponent value set, then the implementation may, at its option, map the value to the nearest element of the float value set. This conversion may result in overflow (in which case the value is replaced by an infinity of the same sign) or underflow (in which case the value may lose precision because it is replaced by a denormalized number or zero of the same sign).
If the value is an element of the double-extended-exponent value set, then the implementation may, at its option, map the value to the nearest element of the double value set. This conversion may result in overflow (in which case the value is replaced by an infinity of the same sign) or underflow (in which case the value may lose precision because it is replaced by a denormalized number or zero of the same sign).
Within an FP-strict expression, mapping values from the float-extended-exponent value set or double-extended-exponent value set is necessary only when a method is invoked whose declaration is not FP-strict and the implementation has chosen to represent the result of the method invocation as an element of an extended-exponent value set.
The expression is a constant expression of type byte, short, char or int.
If the type of an expression can be converted to the type of 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.
If T is an interface type, then a compile-time error occurs unless T is the type java.io.Serializable or the type Cloneable, the only interfaces implemented by arrays.
See §8 for the specification of classes, §9 for interfaces, and §10 for arrays.
The value of veclong cannot be assigned to a Long variable, because Long is a class type other than Object. An array can be assigned only to a variable of a compatible array type, or to a variable of type Object.
Method invocation conversion is applied to each argument value in a method or constructor invocation (§15.9, §15.12): 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.12.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.18.1).
Casting conversion is applied to the operand of a cast operator (§15.16): 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.
Value set conversion (§5.1.8) is applied after the type conversion.
If S is not a final class (§8.1.1), 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.1), then S must implement T, or a compile-time error occurs.
If T is an array type, then T must implement S, or a compile-time error occurs.
If T is a class type that is not final (§8.1.1), 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, then T must be Object (§4.3.2), or a run-time exception is thrown.
If T is an interface type, then a run-time exception is thrown unless T is the type java.io.Serializable or the type Cloneable, the only interfaces 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).
If a run-time exception is thrown, it is a ClassCastException.
Numeric promotion is not a general feature of the Java programming language, but rather a property of the specific definitions of the built-in operations.
In either case, value set conversion (§5.1.8) is then applied.
After the type conversion, if any, value set conversion (§5.1.8) is applied to each operand.

References: §15
 §15
 §15
 §15
 §8
 §9
 §10
 §15