Basically: widening conversions are okay, narrowing conversions require explicit casting.
Conversion of primitives is only done in three distinct cases. Assignment conversion, method call conversion and arithmetic promotion.
Arithmetic promotion of unary operators: If the operand is a byte, short or a char then it is converted into an int unless the operator is ++ or -- in which case no conversion is done. Else, no conversion is done.
Arithmetic promotion of binary operators:
- If one of the operands is a double then the other operand is converted to a double.
- Else if one of the operands is a float then the other operand is converted to a float.
- Else if one of the operands is a long then the other operand is converted to a long.
- Else both operands are converted to ints.
A rule of thumb for object reference conversion (that does not apply in all cases) is that object reference conversion is only permitted when the direction of conversion is up the inheritance tree. That is from sub class to super class.