0.3 treated as a double, so its binary representation takes 64 bits and cannot fit into a float without loss of precision, so you cannot assign it to a float without an explicit cast.
On the other hand, if you assign char int literal within a char type range (e.g. 123), there is no data loss.
Both purposes (int to char variable and double to float variable) require narrowing of the primitive conversion .
JLS 5.2 says
Narrowing down a primitive conversion can be used if the type of the variable is a byte, short, or char, and the value of the constant expression is represented in the type of the variable.
source share